7. Hive解析JSON字符串、JSON数组

Hive解析JSON字符串

1. get_json_object
  • 语法:get_json_object(json_string, path)
    • json_string 是要解析的JSON字符串
    • path 是用于指定要提取的字段路径的字符串
-- 示例1(单层JSON)
SELECT get_json_object('{
                            "name": "John",
                            "age": 30
                         }', '$.name');
-- res: "John"

-- 示例2(嵌套JSON)
SELECT get_json_object('{
                            "person": {
                                "name": "John",
                                "age": 30,
                                "address": {
                                    "street": "123 Main St",
                                    "city": "New York"
                                }
                            }
                         }', '$.person.address.street');
-- res: "123 Main St"
局限性
  • get_json_object 函数的性能会受到 JSON数据的结构和大小 的影响。对于较复杂的嵌套结构,考虑使用Hive的其他函数或自定义函数来处理JSON数据可能更合适。
  • get_json_object 函数每次只能返回一个数据项。
2. json_tuple
  • 语法:json_tuple(json_string, field1, field2, ...)
    • json_string 是要解析的JSON字符串
    • field1、field2 ... 是要提取的字段名
-- 示例1(单层JSON)
select json_tuple('{
                        "name": "zhangsan",
                        "age": 18
                    }','name','age');
-- res: zhangsan	18

-- 示例2(嵌套JSON)
SELECT json_tuple('{
                        "person": {
                            "name": "Alice",
                            "age": 25,
                            "address": {
                                "city": "New York",
                                "country": "USA"
                            }
                        }
                    }', 'person.name', 'person.age', 'person.address.city');
-- res: Alice    25    New York

Hive解析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
1. 嵌套子查询解析JSON数组(使用explode+regexp_replace)

数据如下所示:

array(json_str)
[{“website”:“baidu.com”,“name”:“百度”},{“website”:“google.com”,“name”:“谷歌”}]

解析出其中的website、name

websitename
baidu.com百度
google.com谷歌
-- 思路
-- 1. 使用 regexp_replace 函数将原数据转换为 {"website":"baidu.com","name":"百度"};{"website":"google.com","name":"谷歌"}
-- 2. 使用 split 函数按照 ';' 分割 {"website":"baidu.com","name":"百度"};{"website":"google.com","name":"谷歌"},返回 [{"website":"baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}]
-- 3. 使用 explode 炸裂为
-- {"website":"baidu.com","name":"百度"}
-- {"website":"google.com","name":"谷歌"}
-- 4. 使用 json_tuple 解析数据

-- 实现
-- 1. 先将json数组中的元素解析出来,转化为每行显示
SELECT explode(split(regexp_replace(regexp_replace(
                                            '[{"website":"baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}]',
                                            '\\[|\\]', ''), '\\}\\,\\{', '\\}\\;\\{'), '\\;'));

-- 2. 使用 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) t1;

上面 regexp_replace 函数中的内容解析:

SELECT explode(split(
    regexp_replace(
        regexp_replace(
            '[
                {"website":"baidu.com","name":"百度"},
                {"website":"google.com","name":"谷歌"}
            ]', 
            '\\[|\\]' , ''), --将json数组两边的中括号去掉
            
              '\\}\\,\\{' , '\\}\\;\\{'), --将json数组元素之间的逗号换成分号
                
                 '\\;') --以分号作为分隔符(split函数以分号作为分隔)
          );
          
-- 问:为什么要将json数组中元素之间的逗号换成分号?
-- 答:因为元素内的分隔也是逗号,如果不将元素之间的逗号换掉的话,后面用split函数分隔时也会把元素内的数据给分隔,这不是我们想要的结果。
2. 使用 lateral view 解析JSON数组

当我们数据的结构如下,

idsnames
[1,2,3][{“name”: “daming”, “age”: “15”}, {“name”: “lingling”, “age”: “14”}, {“name”: “tom”, “age”: “17”}]

我们想要获取的数据为,

idname
1daming
2daming
3daming
1lingling
2lingling
3lingling
1tom
2tom
3tom
with json_data as (
    select `array`(1, 2, 3)                        as ids,
           `array`('{"name": "daming", "age": "15"}', '{"name": "lingling", "age": "14"}',
                   '{"name": "tom", "age": "17"}') as json_infos
)

-- 使用json_tuple()报错: org.apache.hadoop.hive.ql.parse.SemanticException:
-- UDTF's are not supported outside the SELECT clause, nor nested in expressions
-- 原因: 未知

-- SELECT id, json_tuple(json_info, 'name')

SELECT id, get_json_object(json_info, '$.name')
FROM json_data
         lateral view explode(json_data.ids) tmp_ids as id
         lateral view explode(json_data.json_infos) tmp_json_infos as json_info;

学习链接

文心一言

ChatGPT

Hive解析Json数组超全讲解

  • 1
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Dataer__

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值