首先說下解析的數據如下:
{"username":"king","actionInfo":{"id":1,"age":"22","partList":[{"code":"123","uname":"king"},{"code":"0012","uname":"king"}]}}
剛開始看,這個就是一個Map結構嵌套了Map,再嵌套了一個數組結構。通常情況下的表結構定義如下:
create table dw_stg.test( username string, actionInfo_id string, actionInfo_age string, actionInfo_partlist array<Map<string,string>> ) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' STORED AS TEXTFILE;
這樣當數據來直接插入到hdfs中,然后利用explode就可以一行轉多行擴展開了。
但是我的需求是這個actionInfo中的字段不固定的,可能是任意的結構,所以我定義的表結構中以string類型存放。如下:
create table dw_stg.test(
username string,
actionInfo string
)
ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe'
STORED AS TEXTFILE;
這時候在做數據清洗時,需要通過json_tuple, get_json_object,explode等函數將string類型解析出來。
[{"code":"123","uname":"king"},{"code":"0012","uname":"king"}]
在字符串時針對上面中括號中等值解析時一直報錯。
最后使用正則的方式,將中括號替換掉,然后在轉化為數組,從而解析成功。參考以下代碼:
select username,ai.id,ai.age,p.uname,p.code from test1 lateral view json_tuple(actioninfo,'id','age','partlist') ai as id,age,partlist lateral view explode(split(regexp_replace(regexp_extract(partlist,'^\\[(.+)\\]$',1),'\\}\\,\\{', '\\}\\|\\|\\{'),'\\|\\|')) partlist as p lateral view json_tuple(p,'code','uname') p as code,uname
這里比較重要的一段是:
explode(split(regexp_replace(regexp_extract('包含中括號的字符串','^\\[(.+)\\]$',1),'\\}\\,\\{', '\\}\\|\\|\\{'),'\\|\\|'))
解析過后的顯示結果: