首页 / JSON
FROM_JSON 按 schema 解析 JSON
FROM_JSON 按指定的 schema 把 JSON 字符串解析成 STRUCT、MAP 或 ARRAY。只有 MaxCompute 和 Spark 同名可用,写法基本一致;StarRocks、Doris 和 Hologres 先转成 JSON 类型再取字段,Hive 和 Flink 只能按路径取值。
各引擎写法
| 引擎 | 支持 | 写法 | 说明 | 依据 |
|---|---|---|---|---|
| MaxCompute | 支持 | from_json(jsonStr, schema) | schema 写法与建表时的类型一致,例如 'a bigint, b double'、'array<bigint>'、'map<string,string>'。返回 ARRAY、MAP 或 STRUCT。STRUCT 的 key 区分大小写,缺失的 key 返回 NULL,类型不匹配的值会被忽略。 | 官方文档 |
| Hologres | 需改写 | json_str::jsonb ->> 'key' | 没有 FROM_JSON。先转成 JSON 或 JSONB,再用 -> 或 ->> 取字段,->> 返回 TEXT。需要展开成多列时可以用 json_populate_record。 | 官方文档 |
| StarRocks | 需改写 | parse_json(str) | 没有 FROM_JSON。parse_json 返回 JSON 类型,而不是 STRUCT 或 MAP。字符串不是合法 JSON 时返回 NULL。取字段可以接 json_query 或 -> 运算符。 | 官方文档 |
| Doris | 需改写 | JSON_PARSE(json_str) | 没有 FROM_JSON。JSON_PARSE 遇到非法 JSON 会报错;希望返回 NULL 时用 JSON_PARSE_ERROR_TO_NULL。取字段用 JSON_EXTRACT 系列函数。 | 官方文档 |
| Hive | 需改写 | json_tuple(jsonStr, k1, k2, ...) | 内置函数中没有 FROM_JSON。一次取多个 key 用 json_tuple,它是 UDTF,要配合 LATERAL VIEW 使用;取单个值用 get_json_object。 | 官方文档 |
| Spark SQL | 支持 | from_json(jsonStr, schema[, options]) | Spark 2.2.0 起提供。schema 用 DDL 字符串,例如 'a INT, b DOUBLE'。options 可以指定 timestampFormat 等解析选项。 | 官方文档 |
| Flink SQL | 需改写 | JSON_VALUE(json, path) / JSON_QUERY(json, path) | 没有 FROM_JSON。JSON_VALUE 取标量值,JSON_QUERY 取对象或数组,返回 JSON 字符串。 | 官方文档 |
迁移注意事项
- MaxCompute 的 from_json 解析成 FLOAT、DOUBLE 或 DECIMAL 时不保证精度。金额类字段建议先按 STRING 取出,再 CAST 成 DECIMAL。
- StarRocks 的 parse_json 和 Doris 的 JSON_PARSE 返回的是 JSON 类型,下游需要 STRUCT 或 MAP 时要再做一次转换,不能直接替换 from_json。
- 非法 JSON 的处理不同:StarRocks 的 parse_json 返回 NULL,Doris 的 JSON_PARSE 直接报错。脏数据较多的表,在 Doris 中改用 JSON_PARSE_ERROR_TO_NULL。
- MaxCompute 的 STRUCT key 区分大小写。JSON 里是 userId、schema 里写成 userid 时,取到的是 NULL,并且不会报错。
示例
解析扩展字段中的 a 和 b
SELECT from_json(ext, 'a bigint, b double') FROM events;SELECT ext::jsonb ->> 'a', ext::jsonb ->> 'b' FROM events;SELECT parse_json(ext) -> '$.a', parse_json(ext) -> '$.b' FROM events;SELECT t.a, t.b FROM events LATERAL VIEW json_tuple(ext, 'a', 'b') t AS a, b;SELECT from_json(ext, 'a BIGINT, b DOUBLE') FROM events;SELECT JSON_VALUE(ext, '$.a'), JSON_VALUE(ext, '$.b') FROM events;