JSON 提取函数是什么
把半结构化数据存成 String 列时,用 JSONExtract 系列函数按路径取值:JSONExtractString、JSONExtractInt、JSONExtractFloat、JSONExtractBool;另有 JSONExtractKeys、JSONExtractArrayRaw、JSONHas 用于探测结构。导入导出常用 JSONEachRow 格式,每行一个 JSON 对象,适合日志与事件数据。较新版本提供原生 JSON 类型与子列访问,但存量表仍以 String 加函数解析为主,行为更可控。
基本信息
| 取值函数 | JSONExtractString(json, 'a', 'b')、JSONExtractInt、JSONExtractFloat、JSONExtractBool |
|---|---|
| 结构探测 | JSONExtractKeys、JSONExtractArrayRaw、JSONHas |
| 格式 | FORMAT JSONEachRow,每行一个 JSON 对象 |
| 路径写法 | 逐层传参或写成点号字符串 |
| 所属系统 | ClickHouse |
典型使用场景
- 日志解析:从 message 列里取出设备、级别等字段再聚合
- 事件表建模:原始 JSON 先落库,再按需提取字段
- 结构探测:用 JSONExtractKeys 看清有哪些键再决定建列
- 条件过滤:先用 JSONHas 判断字段存在,再安全取值
- 数据交换:用 JSONEachRow 直接查询或导入 JSON 行文件
取值与查询
取值与查询
SELECT
JSONExtractString(props, 'device') AS device, -- 按路径取字符串
JSONExtractInt(props, 'level') AS level -- 按路径取整数
FROM events
WHERE JSONHas(props, 'device') -- 先判断键是否存在
LIMIT 10;
-- 直接查询 JSONEachRow 格式的文件
SELECT JSONExtractString(line, 'name') FROM file('data.jsonl', 'JSONEachRow', 'line String');函数读法
| 函数 | 用途 | 返回 |
|---|---|---|
| JSONExtractString | 取字符串 | 缺失时返回空串 |
| JSONExtractInt | 取整数 | 路径或类型不符时返回 0 |
| JSONExtractFloat | 取浮点数 | 同上 |
| JSONHas | 判断键是否存在 | 返回 0 或 1 |
| JSONExtractKeys | 列出顶层键 | 返回数组 |
嵌套路径要按层级依次传参或写成点号字符串,层级写错时函数返回空值而不会报错,排查时先确认路径层级。
高频过滤的 JSON 字段建议在导入时抽成独立列或物化列,逐行解析 JSON 的成本远高于直接读列。
JSONEachRow 与其它格式一样可以在写入与查询两侧使用,做数据交换时比手工拼字符串更不容易出错。
在同一列上反复调用多个 JSONExtract 会重复解析,能复用的取值先用一个表达式算出来,或在写入时把常用字段抽成独立列。
半结构化字段只做少量查询时 String 加函数解析已经够用;如果它要被高频过滤或聚合,抽成独立列或使用原生 JSON 的子列访问更划算。