首页 > 其他分享 >Hive系列之解析JSON数据

Hive系列之解析JSON数据

时间:2022-11-01 10:38:54浏览次数:82  
标签:name johnny get json Hive sex JSON 解析


概述

在数据处理中,经常遇到的一个数据类型就是JSON,MySQL数据库解析JSON,参考​​MySQL 5.7 JSON函数学习​​,
​MySQL json_merge with group by​​。

在大数据执行引擎Hive中,我们也经常会遇到JSON解析的场景。

实战

get_json_object、json_tuple

Hive内部提供大量的内置函数用于处理各种类型的需求,参见官方文档:​​Hive Operators and User-Defined Functions (UDFs)​​​。从这些内置的 UDF 可找到两个用于解析JSON的函数:​​get_json_object​​​ 和 ​​json_tuple​​。

​get_json_object​​​ 语法:​​get_json_object(STRING json_string, STRING path)​

​get_json_object​​​一个只能取一个字段:​​SELECT get_json_object('{"name":"johnny","sex":"男"}', '$.name');​​​ 输出:​​johnny​

如果想要取多个字段,这么写:
​​​SELECT get_json_object('{"name":"johnny","sex":"男"}', '$.name'), get_json_object('{"name":"johnny","sex":"男"}', '$.sex');​​​ 输出:​​johnny 男​

json_tuple 相对于 get_json_object 的优势:一次可以解析多个JSON字段。

语法:​​json_tuple(STRING jsonStr, STRING k1, STRING k2)​

实例:​​SELECT json_tuple('{"name":"johnny","sex":"男"}', 'name', 'sex');​​​ 输出:​​johnny 男​

但是如果有个JSON数组,​​get_json_object​​​处理JSON数组的功能很有限:
​​​SELECT get_json_object('[{"name":"johnny","sex":"男"}, {"name":"lucy","sex":"女"}]', '$.[0].name');​​ 输出:johnny

如果想将整个JSON数组里面的name字段都解析出来,如果这么写将非常麻烦,因为无法确定数组的长度,而且即使确定,由于指定索引字段,可维护性很差。

explode

Hive内置函数

explode() takes in an array (or a map) as an input and outputs the elements of the array (map) as separate rows. UDTFs can be used in the SELECT expression list and as a part of LATERAL VIEW。

​explode()​​接收一个 array 或 map 类型的数据作为输入,然后将 array 或 map 里面的元素按照每行的形式输出。可配合 LATERAL VIEW 一起使用。

比如:

select explode(array('A','B','C'));
A
B
C
select explode(map('A',10,'B',20,'C',30));
A 10
B 20
C 30

用于解析JSON:

SELECT explode(split(regexp_replace(regexp_replace('[{"name":"johnny","sex":"男"}, {"name":"lucy","sex":"女"}]', '{','\\}\\;\\{'),'\\[|\\]',''),'\\;'));

输出:

{"name":"johnny","sex":"男"}
{"name":"lucy","sex":"女"}

几点说明:

  • explode 函数只能接收数组或 map 类型的数据,而 split 函数生成的结果就是数组;
  • 第一个 regexp_replace,外层的那个:将JSON数组元素之间的逗号换成分号
  • 第二个 regexp_replace,内层的那个:将JSON数组两边的中括号去掉

然后可以结合 get_json_object 或 json_tuple 来解析里面的字段:

select json_tuple(json, 'name', 'sex') from(SELECT
explode(split(regexp_replace(regexp_replace('[{"name":"johnny","sex":"男"}, {"name":"lucy","sex":"女"}]', '\\}\\,\\{','\\}\\;\\{'),'\\[|\\]',''),'\\;'))
as json) iteblog;

输出:

johnny 男
lucy 女

自定义函数解析JSON数组

<dependency>
<groupId>org.apache.hive</groupId>
<artifactId>hive-exec</artifactId>
<version>2.1.1</version>
</dependency>

Hive提供强大的自定义函数接口,故可自定义解析JSON数组的UDF:

package com.johnny.demo;
import org.apache.hadoop.hive.ql.exec.Description;
import org.apache.hadoop.hive.ql.exec.UDF;
import org.json.JSONArray;
import org.json.JSONException;
import java.util.ArrayList;
@Description(name = "json_array", value = "_FUNC_(array_string) - Convert a string of a JSON-encoded array to a Hive array of strings.")
public class UDFJsonAsArray extends UDF {
public ArrayList evaluate(String jsonString) {
if (jsonString == null) {
return null;
}
try {
JSONArray extractObject = new JSONArray(jsonString);
ArrayList result = new ArrayList();
for (int ii = 0; ii < extractObject.length(); ++ ii) {
result.add(extractObject.get(ii).toString());
}
return result;
} catch (JSONException | NumberFormatException e) {
return null;
}
}
}

使用:

hive> add jar /root/json.jar;
hive> create temporary function json_array as 'com.johnny.demo.UDFJsonAsArray';
hive> select explode(json_array('[{"name":"johnny","sex":"男"}, {"name":"lucy","sex":"女"}]'));
OK
{"name":"johnny","sex":"男"}
{"name":"lucy","sex":"女"}
hive> select json_tuple(json, 'name', 'sex') from
(SELECT explode(json_array('[{"name":"johnny","sex":"男"}, {"name":"lucy","sex":"女"}]')) as json) iteblog;
johnny 男
lucy 女

参考

如何在 Apache Hive 中解析JSON数组


标签:name,johnny,get,json,Hive,sex,JSON,解析
From: https://blog.51cto.com/u_15851118/5811954

相关文章

  • Java解析cron表达式
    概述Cron表达式是一个字符串,以5或6个空格隔开,分为6或7个域,每一个域代表一个含义,即两种语法格式:SecondsMinutesHoursDayofMonthMonthDayofWeekYear,即:秒分时天月星......
  • BSON VS JSON
       JSONB以二进制格式存储数据,而不是简单的JSONblob。BSONrecordisn’tcontinuouslylittlerthanJSON,butitallowsyoutoeffectivelyskiptherecor......
  • 注解@JSONField和@JsonProperty的简单使用
    本注解的使用,需要引入fastjson依赖<!--添加fastjson依赖--><dependency><groupId>com.alibaba</groupId><artifactId>fastjson</art......
  • WSL 中搭建 hadoop/hive 环境后,在 windows 宿主机下连接 hive 被拒绝
    报错只有:java.net.ConnectException:Connectionrefused这样简短的几行。其真实原因是(在windows11下),WSL有自己的(内部)IP地址。在WSL下执行ipaddr,然后在cmd下......
  • xpath解析
    一、xpath语法XPath使用路径表达式来选取HTML/XML文档中的节点或节点集。节点是通过沿着路径(path)或者步(steps)来选取的。二、选取节点表达式描述nod......
  • JSON
    JSONweb1.0时代早期网站,登录,如果失败,需要刷新页面,才能重新登录;不点击提交按钮,就不知道自己密码输错了;现在大多数的网站,都是局部刷新,不刷新整个页面的情况下,实现页面更新......
  • QJsonObject与(QByteArray、QString)互相转换
    QJsonObjectCbActionSyncManager::getJsonObjectFromByteArray(constQByteArrayjsonString){QJsonDocumentjsonDocument=QJsonDocument::fromJson(jsonString);......
  • Qt用Poppler库解析PDF成图片的简单示例
    解析PDF这里用的是Poppler库,与之相关的库还有MuPDF库,参考了这个链接:​​https://people.freedesktop.org/~aacid/docs/qt5/​​相关链接:​​qt显示pdf——poppler-qt问题​......
  • Qt对Json的生成与解析Demo
    QJsonObject类用于封装JSON对象。JSON对象是键值对,其中键是唯一的字符串,其值由QJsonValue代表。一个QJsonObject可以从QVariantMap转换/被转换。QJsonArray类用于封装JSON数......
  • Go开发 之 JSON转换成Go的struct的快捷方式
    简述以前都是自己按照json的格式来手动写,到现在才知道go有这么方便的方式,记下来哟。Github提供了比较号的处理方式​​https://mholt.github.io/json-to-go/​​效果图使用......