json数组抽取到BI平台后显示为String格式,虽然数据的组织形式看似是json数组,但不能直接针对此数据进行explode。以下介绍通过SparkSQL内置函数的标准处理方式。
Spark 中和 json 相关的函数有(点击函数链接可查看官方语法说明):from_json、get_json_object、to_json、json_tuple、schema_of_json
假设 json 字段存储了非嵌套的内容,且是 json 字符串的数组。
[{"dsid":"uhad","a3":"a3"},{"dsid":"hush"}]
先判断 json 的 schema,再转换回 json 格式:
from_json([被解析的json数组字段], schema_of_json('[{"dsid":"uhad","a3":"a3"},{"dsid":"hush"}]'))
schema_of_json 里的 json 字段可以取一行数据为例,可以直接用解析好的 schema 填充。
from_json([被解析的json数组字段], 'array<struct<a3:string,dsid:string>>')
需要注意的地方:
json数据为非结构化数据,可能存在数组内两个json对象包含的元素不一致的情况,如上面例子中,一个包含dsid和a3,另一个仅包含dsid。选择不一样的json对象来解析,得到的schema也会不同,处理的结果也会不同。
对于嵌套形式的复杂json也能处理,结合1中所述,最终输出的结果是按schema形式组织的。如下所示的json数组,如果按
'array<struct<dsId:string>>'
形式处理,处理后仅会保留dsId相关数据:
处理前:
[ { "dsId": "i2fd25358333330aadd3ae", "created": true, "name": "xx报表", "dirPath": [ { "dirId": "w29946f6333334f07a70a726", "dirName": "根目录" } ], "parentDirName": "根目录", "parentDirId": "w29946f62bb3c4f07a70a726" }, { "dsId": "qdf7e55df03ab4e5c9c46d9d", "created": true, "name": "xx报表", "dirPath": [ { "dirId": "w29946f62bb3c4f07a70a726", "dirName": "根目录" } ], "parentDirName": "根目录", "parentDirId": "w29946f62bb3c4f07a70a726" } ]
处理后:
[ { "dsId": "i2fd25358333330aadd3ae" }, { "dsId": "qdf7e55df03ab4e5c9c46d9d" } ]
接着使用 explode 拆分数组,得到
exploded_string
,即[解析完的json]
explode(from_json([被解析的json数组字段], 'array<struct<a3:string,dsid:string>>'))
最后按 struct 的取数方式,即
.
操作符,exploded_string.wanted_key
从前面的结果里取得 json 的 k-v 结果:
[解析完的json].dsid