Hive的get_json_object 是一个重要的json解析函数,在原始日志的解析中用途广泛。本文主要介绍下该函数的功能,和使用示例。
get_json_object
首先在使用任何函数前,我们先看一下函数的介绍。
0: jdbc:hive2://cdh-manager:10000> desc function get_json_object;
+----------------------------------------------------+
| tab_name |
+----------------------------------------------------+
| get_json_object(json_txt, path) - Extract a json object from path |
+----------------------------------------------------+
大致含义为 : 暗中给定的path路径解析json结构的数据。
那我们给出具体的含义:
- json_text :第一个参数,填写json对象变量。
- path :第二个参数使用$表示json变量标识,然后用 . 或 [] 读取对象或数组;如果输入的json字符串无效,那么返回NULL。
- . : 用于解析层级结构关系
- [] : 用于解析数组或者Map中的元素
注意 :
每次只能返回一个数据项,若想需要解析多个列,则需要多次调用 get_json_object 函数。这个需要注意,这个是相对于get_json_tuple 函数而言的。方便后续和get_json_tuple 做对比。
数据准备:
为了实际测试函数,我们准备了数据如下。
[root@cdh-manager tmp]# hdfs dfs -cat /data/tmp/data.json
{"name":"Michael"}
{"name":"Andy", "age":30}
{"name":"Justin", "age":19}
{"name": {"age":22, "others": { "age":22, "inner_list":[12,13]}}}
创建对应表,并从hdfs中load 数据到数据表中。
+----------------------------------------------------+
| createtab_stmt |
+----------------------------------------------------+
| CREATE TABLE `test.test_json`( |
| `json_test` string) |
| ROW FORMAT SERDE |
| 'org.apache.hadoop.hive.serde2.lazy.LazySimpleSerDe' |
| STORED AS INPUTFORMAT |
| 'org.apache.hadoop.mapred.TextInputFormat' |
| OUTPUTFORMAT |
| 'org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat' |
| LOCATION |
| 'hdfs://cdh-manager:8020/user/hive/warehouse/test.db/test_json' |
| TBLPROPERTIES ( |
| 'transient_lastDdlTime'='1629686406') |
----------------------------------------------------------------
load data inpath "/data/tmp/data.json" overwrite into table test.test_json;
对数据进行实际的解析 :
select
get_json_object(json_test, '$.name.others.inner_list[0]') as a ,
get_json_object(json_test,'$.name') as b
from test_json;
输出
+-------+----------------------------------------------------+
| a | b |
+-------+----------------------------------------------------+
| NULL | Michael |
| NULL | Andy |
| NULL | Justin |
| 12 | {"age":22,"others":{"age":22,"inner_list":[12,13]}} |
+-------+----------------------------------------------------+
通过上述的例子,我想大家已经基本了解 get_json_object 函数的功能了。
下面我们来看看类似功能的函数,json_tuple
json_tuple
Home (Copy) - Apache Samza - Apache Software Foundation
json_tuple
A new json_tuple() UDTF is introduced in Hive 0.7. It takes a set of names (keys) and a JSON string, and returns a tuple of values using one function. This is much more efficient than calling GET_JSON_OBJECT to retrieve more than one key from a single JSON string. In any case where a single JSON string would be parsed more than once, your query will be more efficient if you parse it once, which is what JSON_TUPLE is for. As JSON_TUPLE is a UDTF, you will need to use the LATERAL VIEW syntax in order to achieve the same goal.
上面讲了一大堆,可能大家看的也是云里雾里的,简单的来讲,get_json_tuple 就是一个可以一次解析出多个数据的函数。这里注意下,json_tuple 是 udtf 而不是 udf
官网上给出了一个这样的例子,来对比两个函数
For example,
|
should be changed to:
|
上面的例子说明作用是相同的,json_tuple 结合 lateral view 可以和 get_json_tuple 产生过相同的作用。
但是刚才的数据只是解了一层的数据,我们如何同时解析多个层级的嵌套数据呢,这就需要json_tuple 和 get_json_object 同时使用了。
select
b.b1 ,
get_json_object(b.b1, '$.age') as c1
from test.test_json
lateral view json_tuple(json_test, 'name') b as b1 ;
0: jdbc:hive2://cdh-manager:10000> select b.b1 , get_json_object(b.b1, '$.age') as c1 from test.test_json lateral view json_tuple(json_test, 'name') b as b1 ;
+----------------------------------------------------+-------+
| b.b1 | c1 |
+----------------------------------------------------+-------+
| Michael | NULL |
| Andy | NULL |
| Justin | NULL |
| {"age":22,"others":{"age":22,"inner_list":[12,13]}} | 22 |
+----------------------------------------------------+-------+
此外,解析一层json, json_tuple也可以实现。
示例 :
select json_tuple(json_test,'name') from test.test_json;
+----------------------------------------------------+
| c0 |
+----------------------------------------------------+
| Michael |
| Andy |
| Justin |
| {"age":22,"others":{"age":22,"inner_list":[12,13]}} |
+----------------------------------------------------+
总结
get_json_object 和 json_tuple 都是重要的json解析函数,get_json_object 在于提取某一个值,json_tuple 一次可以提取多个值。