class括号里的object_Hive里七个函数玩转Json

小编最近有点忙哈哈哈(好吧也有点偷懒

今天的信息挺实用的 

目录:

hive里实用函数介绍

实际应用举例

讲解函数的时候也会讲解例子,比较简单,后面实际应用稍稍稍复杂,但是异曲同工

如果你掌握了.... 

  • get_json_object 

  • json_tuple 

  • lateral view 

  • explode 

  • split 

  • regexp_replace

  • regexp_extract 

这几个函数,应该可以随意解析json字段了

d906c3d2a3aabfd5b58fbb75a9aab0c5.gif

get_json_object 

get_json_object(json_string, '$.key')

字面意思获取json的object,我们知道json是键值对的形式,所以只要我们有key就可以得到value,比如python里的dict[key] 可以得到value。

1)单层嵌套

举例:json串如下,我们要获取这个人的name

{  "id":123,   "name":"kk",   "age":20}

解答: 

select    get_json_object(        '{"id":123,"name":"kk","age":20}',        '$.name')from    dual

结果:

70584794a119869c5e49f5e041feb84f.png

2)多层嵌套

举例:多层嵌套格式,你想要c的value

{ "a": { "b": { "c": 123 }} }

解答

select     get_json_object('{ "a": { "b": { "c": 123 }} }', '$.a.b.c')from    dual

结果

9f745fe72a1097f8f430872a86536ca4.png

d906c3d2a3aabfd5b58fbb75a9aab0c5.gif

json_tuple 

同时获取一个json串里多个字段信息

json_tuple(json_string, 'key1','key2' ....)
{   "id":123,    "name":"kk",    "age":20 }

解答

-- 同时得到name 和age

select json_tuple('{"id":123,"name":"kk","age":20}',       'name','age') from dual

结果

65a339ef9bde26faab4140b8fd1c7da6.png

d906c3d2a3aabfd5b58fbb75a9aab0c5.gif

explode / lateral view

explode:将hive一行中复杂的(array/map)结构拆分成多行,接受一组数据但是给你拆成多行输出;

lateral view 一般和explode连用,会将explode以及其他的变换放进一个虚拟表中

explode:

1) 操作array 

select explode(array_col) as new_col from table_name
  • array_col 要被操作的array

  • new_col 操作得到的对应列

2)操作map

select explode(map_col) as (may_key_col, may_value_col) from table_name
  • map_col 为map类型的字段

  • may_key_col, may_value_col 分别对应map_col被拆分之后的map映射里的key 和 value

搬运了一个网上的例子(我好懒

https://cloud.tencent.com/developer/article/1437884

比如:你有这样一个表

5d9902617dd7f39374840913cd73a554.png

你会发现第二列subordinates是合并的,那我们想要拆开成一对一的形式

select name,subordinate from employees  lateral view explode(subordinates) subordinates_table as subordinate

结果

20fa890e9553c7b6e62182ac6f1db74f.png

d906c3d2a3aabfd5b58fbb75a9aab0c5.gif

split 

split:就是分割的意思,大家在python 里应该很熟悉了,这里差不多的用法,要告诉程序以什么字符位置进行拆分

split(str, regex)

先传入你要拆分的string,然后输入拆分规则

比如:用逗号拆分

select split('a,b,c',',')

e97939844384931680a0037d52d4a81c.png

拆分并且提取第一个数值--以此类推

 select split('a,b,c',',')[0]

8e45dc5f9712f820c4944933fcab3337.png

同理拆分 'ijsdeff:efizjef:ezijeife:' 用':' 冒号分割

d906c3d2a3aabfd5b58fbb75a9aab0c5.gif

regexp_extract

regex和正则有关,即按照正则规则提取

regexp_extract(str, regexp,index)
  • str:要被操作的string

  • regexp:你制定的规则

  • index:返回结果,默认是1

         -- 0返回所有的正则表达式要求

         --  1表示返回正则表达式中第一个() 对应的结果

(为什么有01操作呢,因为你不一定只有一个规定,每个规则都单独放在一个()里;如果是0则返回所有的要求,非0就看你告诉他返回第几个括号里的规则;看下文举例子就清楚) 

举例:

想要提取a319218abc这里的数字

select regexp_extract('a319218abc','([0-9]+)',0) from dual

这里只有一个([0-9]+)正则要求,所以第三个参数01都一样

结果

9b993c8295a12a529e1e9515adc99108.png

举例: 

要求变成两个([0-9]+)([a-z]+)

第一个()要求提取数字,第二个()要求提取字母

0的结果 - 返回所有要求的结果

select regexp_extract('a319218abc///','([0-9]+)([a-z]+)',0) from dual

d062fc35335bb1ac920641dc55f57fef.png

1的结果 - 只返回了第一个要求的结果

7968dda4b1aaf828889d5c02395ed73b.png

d906c3d2a3aabfd5b58fbb75a9aab0c5.gif

regexp_replace

理解为excel里的搜索以及替换

REGEXP_REPLACE(stringA, stringB,stringC ]

简单粗暴;stringA你要操作的,stringB,你的规则pattern,stringC你要换成啥

举例:我要把这里的所有的/变成空格 abc/efc/ooc

select regexp_replace('abc/efc/ooc','/',' ') from dual

83665d77be29201a86f34f382a5f0eff.png

d906c3d2a3aabfd5b58fbb75a9aab0c5.gif

看起来简单,合并起来就可以解决比较复杂的问题

案例: 

我们有一个json串,我想得到两列,一列是它的key,一列是他的value

 '{"70a_10y_1#[0,1]":200,  "70a_15y_1#[0,100]":290,  "f_30y_234#[0,1]":100}'

思路

  • 先提取大括号以内的信息,用regexp_extract 

  • 用',"' 逗号和引号的组合分割(比如你看200后面是逗号和引号,290后面也是。

  • 用explode把一行变成多行,这样结果是

82eb442d8f27eb399c5c8012d09f38ce.png

  • 然后我们再用extract提取key 和value

        -- ( 提取引号之前的信息 -- 为key

            ( 提取引号之后的数字为 -- value

select    (regexp_extract(t.test, '(.*?)"',1)) as b,    (regexp_extract(t.test, ':([0-9]+)', 1)) as afrom    (        select            explode(                split(                    regexp_extract(                        '{"70a_10y_1#[0,1]":200,"70a_15y_1#[0,100]":290,"f_30y_234#[0,1]":100}',                        '^\\{"(.+)\\}$',                        1                    ),                    ',"'                )            ) as test    ) t

5aa927be924b15671de58da021768448.png

基础的看不会怎么复杂,但是正则的功能有多强大,大家还是有目共睹的哈哈,在这个基础上大家可以去hive里玩转json,我这个案例肯定不是最简单的办法。

END