irpas技术客

Hive_Hive中的Json数据解析函数 get_json_object & json_tuple_高达一号

未知 2673

? 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

https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=69408918#Home(Copy)-json_tuple

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,

select a.timestamp, get_json_object(a.appevents,?'$.eventid'), get_json_object(a.appenvets,?'$.eventname') from log a;

should be changed to:

select a.timestamp, b.*

from log a lateral view json_tuple(a.appevent,?'eventid',?'eventname') b as f1, f2;

上面的例子说明作用是相同的,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 一次可以提取多个值。


1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。

标签: #get_json_object #1111