我有很多json数组存储在一个表(jt)中,如下所示:
[{"ts":1403781896,"id":14,"log":"show"},{"ts":1403781896,"id":14,"log":"start"}]
[{"ts":1403781911,"id":14,"log":"press"},{"ts":1403781911,"id":14,"log":"press"}]
每个数组都是一个记录。
我想解析这个表,以获得一个包含3个字段的新表(日志):ts,id,log。 我试图使用get_json_object方法,但似乎该方法与json数组不兼容,因为我只获取空值。
这是我测试过的代码:
CREATE TABLE logs AS
SELECT get_json_object(jt.value, '$.ts') AS ts,
get_json_object(jt.value, '$.id') AS id,
get_json_object(jt.value, '$.log') AS log
FROM jt;
我尝试使用其他功能,但它们看起来非常复杂。 谢谢! :)
更新! 我通过执行正则表达式解决了我的问题:
CREATE TABLE jt_reg AS
select regexp_replace(regexp_replace(value,'\\}\\,\\{','\\}\\\n\\{'),'\\[|\\]','') as valuereg from jt;
CREATE TABLE logs AS
SELECT get_json_object(jt_reg.valuereg, '$.ts') AS ts,
get_json_object(jt_reg.valuereg, '$.id') AS id,
get_json_object(jt_reg.valuereg, '$.log') AS log
FROM ams_json_reg;
答案 0 :(得分:6)
使用爆炸()功能
hive (default)> CREATE TABLE logs AS
> SELECT get_json_object(single_json_table.single_json, '$.ts') AS ts,
> get_json_object(single_json_table.single_json, '$.id') AS id,
> get_json_object(single_json_table.single_json, '$.log') AS log
> FROM
> (SELECT explode(json_array_col) as single_json FROM jt) single_json_table ;
Automatically selecting local only mode for query
Total MapReduce jobs = 3
Launching Job 1 out of 3
Number of reduce tasks is set to 0 since there's no reduce operator
hive (default)> select * from logs;
OK
ts id log
1403781896 14 show
1403781896 14 start
1403781911 14 press
1403781911 14 press
Time taken: 0.118 seconds, Fetched: 4 row(s)
hive (default)>
其中json_array_col是jt中保存jsons数组的列。
hive (default)> select json_array_col from jt;
json_array_col
["{"ts":1403781896,"id":14,"log":"show"}","{"ts":1403781896,"id":14,"log":"start"}"]
["{"ts":1403781911,"id":14,"log":"press"}","{"ts":1403781911,"id":14,"log":"press"}"]
答案 1 :(得分:4)
我遇到了这个问题,JSON数组作为字符串存储在hive表中。
解决方案有点hacky和丑陋,但它的工作原理并不需要serdes或外部UDF
SELECT
get_json_object(single_json_table.single_json, '$.ts') AS ts,
get_json_object(single_json_table.single_json, '$.id') AS id,
get_json_object(single_json_table.single_json, '$.log') AS log
FROM ( SELECT explode (
split(regexp_replace(substr(json_array_col, 2, length(json_array_col)-2),
'"}","', '"}",,,,"'), ',,,,')
) FROM src_table) single_json_table;
我打破了排队,这样会更容易阅读。 我使用substr()去掉第一个和最后一个字符,删除[和]。然后我使用regex_replace来匹配json数组中记录之间的分隔符,并添加或更改分隔符,使其成为唯一的,然后可以使用split()将字符串转换为json对象的hive数组。然后可以与之前的解决方案中描述的explode()一起使用。
注意,此处使用的分隔符正则表达式("}",")不能使用原始数据集...正则表达式必须是(&#34) ;},\ {")然后替换将需要"} ,,,, {"例如..
split(regexp_replace(substr(json_array_col, 2, length(json_array_col)-2),
'"},\\{"', '"},,,,{"'), ',,,,')
答案 2 :(得分:2)
因为get_json_object不支持json数组字符串,所以你可以连接到json对象,如下所示:
SELECT
get_json_object(concat(concat('{"root":', jt.value), '}'), '$.root')
FROM jt;