让决策更智能
新一代智能数据分析平台

如何使用ETL解析json

观小远发表于:2021年04月30日 08:41:20更新于:2021年04月30日 08:45:17

json数组抽取到BI平台后显示为String格式,虽然数据的组织形式看似是json数组,但不能直接针对此数据进行explode。以下介绍通过SparkSQL内置函数的标准处理方式。

Spark 中和 json 相关的函数有(点击函数链接可查看官方语法说明):from_jsonget_json_objectto_jsonjson_tupleschema_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>>')

需要注意的地方:

  1. json数据为非结构化数据,可能存在数组内两个json对象包含的元素不一致的情况,如上面例子中,一个包含dsid和a3,另一个仅包含dsid。选择不一样的json对象来解析,得到的schema也会不同,处理的结果也会不同。

  2. 对于嵌套形式的复杂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

image.png


    您需要登录后才可以回复