全球体育app怎么下载

上海阀门简介 一文学会Hive解析Json数组
发布日期:2021-07-19 01:31    点击次数:163

本文转载自微信公多号「五分钟学大数据」,作者园陌。转载本文请有关五分钟学大数据公多号。

在Hive中会有很无数据是用Json格式来存储的,如开发人员对APP上的页面进走埋点时,会将多个字段存放在一个json数组中,因此数据平台调用数据时,要对埋点数据进走解析。接下来就聊聊Hive中是如何解析json数据的。

Hive自带的json解析函数

1. get_json_object

语法:get_json_object(json_string, '$.key') 表明:解析json的字符串json_string,返回path指定的内容。倘若输入的json字符串无效,那么返回NULL。这个函数每次只能返回一个数据项。 示例:
select  get_json_object('{"name":"zhangsan","age":18}','$.name');  

效果:

name zhangsan

倘若既要解析name字段,也解析age字段,则能够如许写:

select  get_json_object('{"name":"zhangsan","age":18}','$.name'), get_json_object('{"name":"zhangsan","age":18}','$.age'); 

但是倘若要解析的字段有许多,再如许写就太麻烦了,以是就有了 json_tuple 这个函数。

2. json_tuple

语法:json_tuple(json_string, k1, k2 ...) 表明:解析json的字符串json_string,可指定多个json数据中的key,返回对答的value。倘若输入的json字符串无效,那么返回NULL。 示例:
select  b.name ,b.age from tableName a lateral view json_tuple('{"name":"zhangsan","age":18}','name','age') b as name,age; 
效果: name age zhangsan 18

仔细:上面的json_tuple函数中异国$.

倘若在操纵json_tuple函数时添上$.就会解析战败:上海阀门简介

select  b.name ,b.age from tableName a lateral view json_tuple('{"name":"zhangsan","age":18}','$.name','$.age') b as name,age; 

效果:

name age NULL NULL

字段全是NULL,以是json_tuple函数不必要添$.了,否则会解析不到。

总结:json_tuple相等于get_json_object的上风就是一次能够解析多个json字段。但是倘若吾们有个json数组,这两个函数都无法处理。

Hive解析json数组 一、嵌套子查询解析json数组

倘若有一个hive外,外中 json_str 字段的内容如下:

json_str [{"website":"baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}]

吾们想把这个字段解析出来,形成如下的组织:

website name baidu.com 百度 google.com 谷歌

要解析这个json数组,仅用上面介绍的两个函数就解析不出来了,还需用到如下介绍的几个函数:

explode函数 语法:explode(Array OR Map) 表明:explode()函数授与一个array或者map类型的数据行为输入,然后将array或map内里的元素根据每走的样式输出,即将hive一列中复杂的array或者map组织拆分成多走表现,也被称为列转走函数。 示例:
-- 解析array hive> select explode(array('A','B','C')); OK A B C -- 解析map hive> select explode(map('A',10,'B',20,'C',30)); OK A       10 B       20 C       30 
regexp_replace函数 语法: regexp_replace(string A, string B, string C) 表明:将字符串A中的相符java正则外达式B的片面替换为C。仔细,在有些情况下要操纵转义字符,相通oracle中的regexp_replace函数。 示例:
hive> select regexp_replace('foobar', 'oo|ar', '');  OK fb 

上述示例将字符串中的 oo 或 ar 替换为''。

有了上述几个函数,接下来吾们来解析json_str字段的内容:

先将json数组中的元素解析出来上海阀门简介,转化为每走表现:

hive> SELECT explode(split(regexp_replace(regexp_replace('[{"website":"baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}]', '\\]',''),'\\}\\,\\{','\\}\\;\\{'),'\\;')); OK {"website":"baidu.com","name":"百度"} {"website":"google.com","name":"谷歌"} 

对上述sql进走简要表明:

SELECT explode(split(     regexp_replace(         regexp_replace(             '[                 {"website":"baidu.com","name":"百度"},                 {"website":"google.com","name":"谷歌"}             ]',              '\\[|\\]' , ''), 将json数组双方的中括号往失踪                            '\\}\\,\\{' , '\\}\\;\\{'), 将json数组元素之间的逗号换成分号                                   '\\;') 以分号行为分隔符(split函数以分号行为分隔)           );   

为什么要将json数组元素之间的逗号换成分号?

由于元素内的分隔也是逗号,倘若不将元素之间的逗号换失踪的话,后面用split函数分隔时也会把元素内的数据给分隔,这不是吾们想要的效果。

上步已经把一个json数组转化为多个json字符串了,接下来结相符son_tuple函数来解析json内里的字段:

select  json_tuple(explode(split( regexp_replace(regexp_replace('[{"website":"baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}]', '\\[|\\]',''),'\\}\\,\\{','\\}\\;\\{'),'\\;'))  ) , 'website', 'name') ; 

实走上述语句,效果报错了:

FAILED: SemanticException [Error 10081]: UDTF's are not supported outside the SELECT clause, nor nested in expressions 

有趣是UDTF函数不克写在别的函数内,也就是这边的explode函数不克写在json_tuple内里。

既然explode函数不克写在别的json_tuple内里,那吾们能够用子查询手段,如下所示:

select json_tuple(json, 'website', 'name')  from ( select explode(split(regexp_replace(regexp_replace('[{"website":"baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}]', '\\[|\\]',''),'\\}\\,\\{','\\}\\;\\{'),'\\;'))  as json) t; 

实走上述语句,异国报错,实走效果如下:

www.baidu.com   百度 google.com      谷歌 
二 操纵 lateral view 解析json数组

hive外中 goods_id 和 json_str 字段的内容如下:上海阀门简介

goods_id json_str 1,2,3 [{"source":"7fresh","monthSales":4900,"userCount":1900,"score":"9.9"},{"source":"jd","monthSales":2090,"userCount":78981,"score":"9.8"},{"source":"jdmart","monthSales":6987,"userCount":1600,"score":"9.0"}]

现在标:把 goods_id 字段和 json_str 字段中的monthSales解析出来。

下面吾们就最先解析:

拆分goods_id字段及将json数组转化成多个json字符串:

select  explode(split(goods_id,',')) as good_id, explode(split(regexp_replace(regexp_replace(json_str , '\\[|\\]',''),'\\}\\,\\{','\\}\\;\\{'),'\\;'))  as sale_info  from tableName; 

实走上述语句,效果报错:

FAILED: SemanticException 3:0 Only a single expression in the SELECT clause is supported with UDTF's. Error encountered near token 'sale_info' 

有趣是用UDTF的时候,SELECT 只声援一个字段。而上述语句select中有两个字段,以是报错了。

那怎么办呢,要解决这个题目,还得再介绍一个hive语法:

lateral view

lateral view用于和split、explode等UDTF一首操纵的,能将一走数据拆分成多走数据,在此基础上能够对拆分的数据进走聚相符,lateral view最先为原首外的每走调用UDTF,UDTF会把一走拆分成一走或者多走,lateral view在把效果组相符,产生一个声援又名外的虚拟外。

示例:

倘若吾们有一张用户有趣喜欢益外 hobbies_table,它有两列数据,第一列是name,第二列是用户有趣喜欢益的id_list,是一个数组,存储有趣喜欢益的id值:

name id_list zhangsan [1,2,3] lisi [3,4,5]

吾们要统计一切有趣id在一切用户中展现的次数:

对有趣id进走解析:

SELECT name, hobby_id  FROM hobbies_table  LATERAL VIEW explode(id_list) tmp_table AS hobby_id; 

上述sql实走效果:

name hobby_id zhangsan 1 zhangsan 2 zhangsan 3 lisi 3 lisi 4 lisi 5

2. 根据hobby_id进走分组聚相符即可:

SELECT hobby_id ,count(1) client_num FROM hobbies_table  LATERAL VIEW explode(id_list) tmp_table AS hobby_id group by hobby_id; 

效果:

hobby_id client_num 1 1 2 1 3 2 4 1 5 1

介绍完 lateral view 之后,吾们再来解决上面遇到的用UDTF的时候,SELECT 只声援一个字段的题目:

select good_id,get_json_object(sale_json,'$.monthSales') as monthSales from tableName  LATERAL VIEW explode(split(goods_id,','))goods as good_id  LATERAL VIEW explode(split(regexp_replace(regexp_replace(json_str , '\\[|\\]',''),'\\}\\,\\{','\\}\\;\\{'),'\\;')) sales as sale_json; 

仔细:上述语句是三个外笛卡尔积的效果,以是此手段适用于数据量不是很大的情况。

上述语句实走效果如下:

goods_id monthSales 1 4900 1 2090 1 6987 2 4900 2 2090 2 6987 3 4900 3 2090 3 6987

倘若外中还有其他字段,吾们能够根据其他字段筛选出相符效果的数据。

总结:lateral view清淡和UDTF一首展现,为晓畅决UDTF不批准在select存在多个字段的题目。

【编辑保举】上海阀门简介

Hive中的内部外、外部外、分区外和分桶外 Idea 插件:迅速JSON转对象 高频HIVE-SQL笔试题详解(一) Hive千亿级数据倾斜解决方案 这照样吾最熟识的package.json吗?

Powered by 全球体育app怎么下载 @2013-2021 RSS地图 HTML地图