JSON 函数
There are two sets of functions to parse JSON:
simpleJSON*
(visitParam*
) 用于快速解析受限子集的 JSON。JSONExtract*
用于解析普通 JSON。
simpleJSON (visitParam) functions
ClickHouse 具有用于简化 JSON 的特殊函数。所有这些 JSON 函数都基于对 JSON 可能的强假设。它们尽量做最少的事情,以尽快完成工作。
做出以下假设:
- 字段名称(函数参数)必须是常量。
- 字段名称以某种方式在 JSON 中以规范形式编码。例如:
simpleJSONHas('{"abc":"def"}', 'abc') = 1
,但simpleJSONHas('{"\\u0061\\u0062\\u0063":"def"}', 'abc') = 0
- 在任意嵌套级别上,字段不加区分地进行搜索。如果存在多个匹配字段,则使用第一个匹配项。
- JSON 的字符串文字外部没有空格字符。
simpleJSONHas
检查是否存在名为 field_name
的字段。结果是 UInt8
。
语法
别名: visitParamHas
。
参数
json
— 要搜索字段的 JSON。 Stringfield_name
— 要搜索的字段的名称。 String literal
返回值
- 如果字段存在,则返回
1
,否则返回0
。 UInt8。
示例
查询:
结果:
simpleJSONExtractUInt
从名为 field_name
的字段值解析 UInt64
。如果这是一个字符串字段,它会尝试从字符串的开头解析一个数字。如果字段不存在,或者字段存在但不包含数字,则返回 0
。
语法
别名: visitParamExtractUInt
。
参数
json
— 要搜索字段的 JSON。 Stringfield_name
— 要搜索的字段的名称。 String literal
返回值
- 如果字段存在并且包含数字,则返回从字段解析出的数字, 否则返回
0
。 UInt64。
示例
查询:
结果:
simpleJSONExtractInt
从名为 field_name
的字段值解析 Int64
。如果这是一个字符串字段,它会尝试从字符串的开头解析一个数字。如果字段不存在,或者字段存在但不包含数字,则返回 0
。
语法
别名: visitParamExtractInt
。
参数
json
— 要搜索字段的 JSON。 Stringfield_name
— 要搜索的字段的名称。 String literal
返回值
- 如果字段存在并且包含数字,则返回从字段解析出的数字, 否则返回
0
。 Int64。
示例
查询:
结果:
simpleJSONExtractFloat
从名为 field_name
的字段值解析 Float64
。如果这是一个字符串字段,它会尝试从字符串的开头解析一个数字。如果字段不存在,或者字段存在但不包含数字,则返回 0
。
语法
别名: visitParamExtractFloat
。
参数
json
— 要搜索字段的 JSON。 Stringfield_name
— 要搜索的字段的名称。 String literal
返回值
- 如果字段存在并且包含数字,则返回从字段解析出的数字, 否则返回
0
。 Float64。
示例
查询:
结果:
simpleJSONExtractBool
从名为 field_name
的字段值解析 true/false 值。结果为 UInt8
。
语法
别名: visitParamExtractBool
。
参数
json
— 要搜索字段的 JSON。 Stringfield_name
— 要搜索的字段的名称。 String literal
返回值
如果字段的值为 true
,则返回 1
,否则返回 0
。这意味着该函数将返回 0
包括(而不仅仅是在以下情况下):
- 如果字段不存在。
- 如果字段包含的值为 “true” 的字符串,例如:
{"field":"true"}
。 - 如果字段包含的值为
1
的数值。
示例
查询:
结果:
simpleJSONExtractRaw
返回名为 field_name
的字段的值作为 String
,包括分隔符。
语法
别名: visitParamExtractRaw
。
参数
json
— 要搜索字段的 JSON。 Stringfield_name
— 要搜索的字段的名称。 String literal
返回值
- 如果字段存在,则返回字段的值作为字符串,包括分隔符,否则返回空字符串。
String
示例
查询:
结果:
simpleJSONExtractString
从名为 field_name
的字段值中解析 String
(用双引号括起来)。
语法
别名: visitParamExtractString
。
参数
json
— 要搜索字段的 JSON。 Stringfield_name
— 要搜索的字段的名称。 String literal
返回值
- 返回字段的未转义值作为字符串,包括分隔符。如果字段不包含用双引号括起来的字符串,如果解码失败或字段不存在,则返回空字符串。 String。
实现细节
目前不支持格式为 \uXXXX\uYYYY
的代码点,它们被转换为 CESU-8,而不是 UTF-8。
示例
查询:
结果:
JSONExtract functions
以下函数基于 simdjson,旨在满足更复杂的 JSON 解析要求。
isValidJSON
检查传递的字符串是否是有效 JSON。
语法
示例
JSONHas
如果值在 JSON 文档中存在,将返回 1
。如果值不存在,将返回 0
。
语法
参数
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
- 如果值在
json
中存在,则返回1
,否则返回0
。 UInt8。
示例
查询:
元素的最小索引为 1。因此,元素 0 不存在。您可以使用整数访问 JSON 数组和 JSON 对象。例如:
JSONLength
返回 JSON 数组或 JSON 对象的长度。如果值不存在或类型不正确,将返回 0
。
语法
参数
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
- 返回 JSON 数组或 JSON 对象的长度。如果值不存在或者类型不正确,则返回
0
。 UInt64。
示例
JSONType
返回 JSON 值的类型。如果值不存在,将返回 Null=0
(不是通常的 Null,而是 Enum8('Null' = 0, 'String' = 34,...
)。
语法
参数
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
- 返回 JSON 值的类型作为字符串,如果值不存在则返回
Null=0
。 Enum。
示例
JSONExtractUInt
解析 JSON 并提取 UInt 类型的值。
语法
参数
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
- 如果存在,则返回 UInt 值,否则返回
0
。 UInt64。
示例
查询:
结果:
JSONExtractInt
解析 JSON 并提取 Int 类型的值。
语法
参数
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
- 如果存在,则返回 Int 值,否则返回
0
。 Int64。
示例
查询:
结果:
JSONExtractFloat
解析 JSON 并提取 Float 类型的值。
语法
参数
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
- 如果存在,则返回 Float 值,否则返回
0
。 Float64。
示例
查询:
结果:
JSONExtractBool
解析 JSON 并提取布尔值。如果值不存在或类型不正确,则返回 0
。
语法
参数
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
- 返回布尔值如果存在,否则返回
0
。 Bool。
示例
查询:
结果:
JSONExtractString
解析 JSON 并提取字符串。此函数与 visitParamExtractString
函数类似。如果值不存在或类型不正确,将返回空字符串。
语法
参数
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
- 返回从
json
提取的未经转义的字符串。如果解码失败,如果值不存在或类型不正确,则返回空字符串。 String。
示例
JSONExtract
解析 JSON 并提取指定 ClickHouse 数据类型的值。此函数是前面 JSONExtract<type>
函数的通用版本。含义:
JSONExtract(..., 'String')
返回与 JSONExtractString()
完全相同,
JSONExtract(..., 'Float64')
返回与 JSONExtractFloat()
完全相同。
语法
参数
json
— 要解析的 JSON 字符串。 String。indices_or_keys
— 一个零个或多个参数的列表,每个参数可以是字符串或整数。 String, Int*。return_type
— 指定要提取的值类型的字符串。 String。
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
示例
通过传递多个 indices_or_keys 参数引用嵌套值:
结果:
JSONExtractKeysAndValues
从 JSON 中解析键值对,其中值是指定的 ClickHouse 数据类型。
语法
参数
json
— 要解析的 JSON 字符串。 String。indices_or_keys
— 一个零个或多个参数的列表,每个参数可以是字符串或整数。 String, Int*。value_type
— 指定要提取的值的类型的字符串。 String。
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
示例
JSONExtractKeys
解析 JSON 字符串并提取键。
语法
参数
json
— String 有效 JSON。a, b, c...
— 逗号分隔的索引或键,指定在嵌套 JSON 对象中内部字段的路径。每个参数可以是 String通过键获取字段,或 Integer 获取第 N 个字段(从 1 开始索引,负整数从结尾计数)。如果未设置,则将整个 JSON 作为顶级对象解析。可选参数。
返回值
示例
查询:
结果:
JSONExtractRaw
将 JSON 的一部分作为未解析的字符串返回。如果该部分不存在或类型不正确,则返回空字符串。
语法
参数
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
- 将 JSON 的一部分作为未解析的字符串返回。如果该部分不存在或类型不正确,则返回空字符串。 String。
示例
JSONExtractArrayRaw
返回 JSON 数组的元素数组,每个元素表示为未解析的字符串。如果该部分不存在或不是数组,则返回空数组。
语法
参数
indices_or_keys
类型:
- 字符串 = 通过键访问对象成员。
- 正整数 = 从头开始访问第 n 个成员/键。
- 负整数 = 从尾部访问第 n 个成员/键。
返回值
示例
JSONExtractKeysAndValuesRaw
从 JSON 对象中提取原始数据。
语法
参数
json
— String 有效 JSON。p, a, t, h
— 逗号分隔的索引或键,指定在嵌套 JSON 对象中内部字段的路径。每个参数可以是 string 通过键获取字段,或 integer 获取第 N 个字段(从 1 开始索引,负整数从结尾计数)。如果未设置,则整个 JSON 作为顶级对象解析。可选参数。
返回值
- 返回
('key', 'value')
元组的数组。两个元组成员都为字符串。 Array(Tuple(String, String))。 - 如果请求的对象不存在,或输入 JSON 无效,则返回空数组。 Array(Tuple(String, String))。
示例
查询:
结果:
查询:
结果:
查询:
结果:
JSON_EXISTS
如果值在 JSON 文档中存在,则返回 1
。如果值不存在,则返回 0
。
语法
参数
在 21.11 版本之前,参数的顺序是错误的,即 JSON_EXISTS(path, json)
返回值
- 如果值存在于 JSON 文档中,则返回
1
,否则返回0
。
示例
JSON_QUERY
解析 JSON 并将值提取为 JSON 数组或 JSON 对象。如果值不存在,则返回空字符串。
语法
参数
在 21.11 版本之前,参数的顺序是错误的,即 JSON_EXISTS(path, json)
返回值
- 返回提取的 JSON 数组或 JSON 对象的值。否则,如果值不存在,则返回空字符串。 String。
示例
查询:
结果:
JSON_VALUE
解析 JSON 并提取值作为 JSON 标量。如果值不存在,默认情况下返回空字符串。
此函数受以下设置控制:
- 通过 SET
function_json_value_return_type_allow_nullable
=true
,将返回NULL
。如果值是复杂类型(例如:结构、数组、映射),将默认返回空字符串。 - 通过 SET
function_json_value_return_type_allow_complex
=true
,将返回复杂值。
语法
参数
在 21.11 版本之前,参数的顺序是错误的,即 JSON_EXISTS(path, json)
返回值
- 如果值存在,则作为 JSON 标量返回提取的值,否则返回空字符串。 String。
示例
查询:
结果:
toJSONString
将值序列化为 JSON 表示形式。支持各种数据类型和嵌套结构。
64 位 整数 或更大(如 UInt64
或 Int128
)默认用引号括起来。 output_format_json_quote_64bit_integers 控制此行为。
特定值 NaN
和 inf
被替换为 null
。启用 output_format_json_quote_denormals 设置以显示它们。
在序列化 Enum 值时,函数输出其名称。
语法
参数
value
— 要序列化的值。值可以是任何数据类型。
返回值
- 值的 JSON 表示形式。 String。
示例
第一个示例显示了 Map 的序列化。 第二个示例显示了一些特殊值封装在 Tuple 中。
查询:
结果:
另见
JSONArrayLength
返回最外层 JSON 数组中的元素数量。如果输入 JSON 字符串无效,则函数返回 NULL。
语法
别名: JSON_ARRAY_LENGTH(json)
。
参数
json
— String 有效 JSON。
返回值
- 如果
json
是有效的 JSON 数组字符串,则返回数组元素的数量,否则返回 NULL。 Nullable(UInt64)。
示例
jsonMergePatch
返回合并后的 JSON 对象字符串,合并多个 JSON 对象生成。
语法
参数
json
— String 有效 JSON。
返回值
- 如果 JSON 对象字符串有效,返回合并后的 JSON 对象字符串。 String。
示例
JSONAllPaths
返回存储在每行的 JSON 列中的所有路径列表。
语法
参数
json
— JSON。
返回值
- 路径数组。 Array(String)。
示例
JSONAllPathsWithTypes
返回存储在每行的 JSON 列中的所有路径及其数据类型的映射。
语法
参数
json
— JSON。
返回值
- 路径数组。 Map(String, String)。
示例
JSONDynamicPaths
返回存储在 JSON 列中作为单独子列的动态路径列表。
语法
参数
json
— JSON。
返回值
- 路径数组。 Array(String)。
示例
JSONDynamicPathsWithTypes
返回存储在 JSON 列中作为单独子列的动态路径及其类型的映射。
语法
参数
json
— JSON。
返回值
- 路径数组。 Map(String, String)。
示例
JSONSharedDataPaths
返回存储在 JSON 列中的共享数据结构中的路径列表。
语法
参数
json
— JSON。
返回值
- 路径数组。 Array(String)。
示例
JSONSharedDataPathsWithTypes
返回存储在 JSON 列中共享数据结构及其类型的路径的映射。
语法
参数
json
— JSON。
返回值
- 路径数组。 Map(String, String)。
示例