Hive解析Json数组超全讲解(一)

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

在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字段的内容:


  1. 先将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函数分隔时也会把元素内的数据给分隔,这不是我们想要的结果。


       b.上步已经把一个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解析出来。

相关文章
|
1月前
|
存储 缓存 安全
C++数组全解析:从基础知识到高级应用,领略数组的魅力与技巧
C++数组全解析:从基础知识到高级应用,领略数组的魅力与技巧
53 1
|
29天前
|
JSON JavaScript 前端开发
C++ 智能指针与 JSON 处理:高级编程技巧与常见问题解析
C++ 智能指针与 JSON 处理:高级编程技巧与常见问题解析
264 0
|
6天前
|
存储 索引 Python
深入解析NumPy数组的形状与重塑
【4月更文挑战第17天】本文深入解析了NumPy数组的形状和重塑。数组形状是表示数组维度和大小的元组,可通过`shape`属性获取。重塑允许改变数组形状而不改数据,需保证元素总数不变。`reshape`方法用于重塑,其中`-1`可让NumPy自动计算尺寸。注意重塑遵循元素总数相等、仅一次`-1`、内存存储顺序及返回新数组的原则。理解和掌握这些概念对高效使用NumPy处理多维数组至关重要。
|
11天前
|
存储 JSON JavaScript
「Python系列」Python JSON数据解析
在Python中解析JSON数据通常使用`json`模块。`json`模块提供了将JSON格式的数据转换为Python对象(如列表、字典等)以及将Python对象转换为JSON格式的数据的方法。
27 0
|
29天前
|
JSON JavaScript 数据格式
【深入探究C++ JSON库】解析JSON元素的层级管理与遍历手段
【深入探究C++ JSON库】解析JSON元素的层级管理与遍历手段
86 2
|
29天前
|
存储 算法 Serverless
【软件设计师备考 专题 】数据结构深度解析:从数组到图
【软件设计师备考 专题 】数据结构深度解析:从数组到图
56 0
|
29天前
|
机器学习/深度学习 存储 Java
揭秘数组:数据结构的基石与代码实践解析
揭秘数组:数据结构的基石与代码实践解析
9 0
|
29天前
|
XML JSON API
深入解析C++ JSON库:nlohmann::json:: parse的内部机制与应用
深入解析C++ JSON库:nlohmann::json:: parse的内部机制与应用
47 0
|
1月前
|
JSON 数据格式
人脸检测解析json的工具类face_test
人脸检测解析json的工具类face_test
13 0
|
1月前
|
JSON JavaScript 前端开发
如何在Python中解析JSON响应?
【2月更文挑战第26天】【2月更文挑战第92篇】如何在Python中解析JSON响应?

推荐镜像

更多