hive json 获取_hive之Json解析(普通Json和Json数组)

本文介绍了如何在Hive中解析Json数据,包括使用get_json_object函数获取单个字段,利用json_tuple一次性解析多个字段,以及处理Json数组的方法,包括Hive内置的explode函数结合正则表达式操作和自定义UDF函数的使用。
摘要由CSDN通过智能技术生成

一、数据准备

现准备原始json数据(test.json)如下:

{"movie":"1193","rate":"5","timeStamp":"978300760","uid":"1"}

{"movie":"661","rate":"3","timeStamp":"978302109","uid":"1"}

{"movie":"914","rate":"3","timeStamp":"978301968","uid":"1"}

{"movie":"3408","rate":"4","timeStamp":"978300275","uid":"1"}

{"movie":"2355","rate":"5","timeStamp":"978824291","uid":"1"}

{"movie":"1197","rate":"3","timeStamp":"978302268","uid":"1"}

{"movie":"1287","rate":"5","timeStamp":"978302039","uid":"1"}

{"movie":"2804","rate":"5","timeStamp":"978300719","uid":"1"}

{"movie":"594","rate":"4","timeStamp":"978302268","uid":"1"}

现在将数据导入到hive中,并且最终想要得到这么一个结果:

可以使用:内置函数(get_json_object)或者自定义函数完成

二、get_json_object(string json_string, string path)

返回值:String

说明:解析json的字符串json_string,返回path指定的内容。如果输入的json字符串无效,那么返回NUll,这个函数每次只能返回一个数据项。

0: jdbc:hive2://hadoop3:10000> select get_json_object('{"movie":"594","rate":"4","timeStamp":"978302268","uid":"1"}','$.movie');

1、创建json表并将数据导入

0: jdbc:hive2://master:10000> create table json(data string);

No rows affected (0.572 seconds)

0: jdbc:hive2://master:10000> load data local inpath '/home/hadoop/json.txt' into table json;

No rows affected (1.046 seconds)

0: jdbc:hive2://master:10000> select get_json_object(data,'$.movie') as movie from json;

三、json_tuple(jsonStr, k1, k2, ...)

参数为一组键k1,k2,。。。。。和json字符串,返回值的元组。该方法比get_json_object高效,因此可以在一次调用中输入多次键

0: jdbc:hive2://master:10000> select b.b_movie,b.b_rate,b.b_timeStamp,b.b_uid from json a lateral view

json_tuple(a.data,'movie','rate','timeStamp','uid') b as b_movie,b_rate,b_timeStamp,b_uid;

注意点:

json_tuple相当于get_json_object的优势就是一次可以解析多个Json字段。但是如果我们有个Json数组,这两个函数都无法处理

四、Json数组解析

1、使用Hive自带的函数解析Json数组

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

hive> select explode(array('A','B','C'));

OK

A

B

C

Time taken:4.879 seconds, Fetched: 3row(s)

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

OK

A10B20C30Time taken:0.261 seconds, Fetched: 3 row(s)

这个explode函数和我们解析json数据是有关系的,我们可以使用explode函数将json数组里面的元素按照一行一行的形式输出:

hive> SELECT explode(split(regexp_replace(regexp_replace('[{"website":"www.baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}]', '\\]',''),'\\}\\,\\{','\\}\\;\\{'),'\\;'));

OK

{"website":"www.baidu.com","name":"百度"}

{"website":"google.com","name":"谷歌"}

Time taken:0.14 seconds, Fetched: 2 row(s)

说明:

SELECT explode(split(

regexp_replace(

regexp_replace('[

{"website":"www.baidu.com","name":"百度"},

{"website":"google.com","name":"谷歌"}

]',

'\\[|\\]',''), --将 Json 数组两边的中括号去掉'\\}\\,\\{' --将 Json 数组元素之间的逗号换成分号

,'\\}\\;\\{'),'\\;')); --以分号作为分隔符

结合 get_json_object 或 json_tuple 来解析里面的字段:

hive> select json_tuple(json, 'website', 'name') from (SELECT explode(split(regexp_replace(regexp_replace('[{"website":"www.baidu.com","name":"百},{"website":"google.com","name":"谷歌"}]', '\\[|\\]',''),'\\}\\,\\{','\\}\\;\\{'),'\\;')) asjson) test;

OK

www.baidu.com 百度

google.com 谷歌

Time taken:0.283 seconds, Fetched: 2 row(s)

2、自定义函数解析JSON数组

虽然可以使用Hive自带的函数类解析Json数组,但是使用起来有些麻烦。Hive提供了强大的自定义函数(UDF)的接口,我们可以使用这个功能来编写解析JSON数组的UDF。具体测试过程如下:

org.apache.hive

hive-exec

2.1.1

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 classJsonArray extends UDF{public ArrayListevaluate(String jsonString) {if (jsonString == null) {return null;

}try{

JSONArray extractObject= newJSONArray(jsonString);

ArrayList result = new ArrayList();for (int ii = 0; ii < extractObject.length(); ++ii) {

result.add(extractObject.get(ii).toString());

}returnresult;

}catch(JSONException e) {return null;

}catch(NumberFormatException e) {return null;

}

}

}

将上面的代码进行编译打包,jar包名为:HiveJsonTest-1.0-SNAPSHOT.jar

hive> add jar /mnt/HiveJsonTest-1.0-SNAPSHOT.jar;

Added [/mnt/HiveJsonTest-1.0-SNAPSHOT.jar] to classpath

Added resources: [/mnt/HiveJsonTest-1.0-SNAPSHOT.jar]

hive> create temporary function json_array as 'JsonArray';

OK

Time taken:0.111 seconds

hive> select explode(json_array('[{"website":"www.baidu.com","name":"百度"},{"website":"google.com"name":"谷歌"}]'));

OK

{"website":"www.baidu.com","name":"百度"}

{"website":"google.com","name":"谷歌"}

Time taken:10.427 seconds, Fetched: 2 row(s)

hive> select json_tuple(json, 'website', 'name') from (SELECT explode(json_array('[{"website":"www.baidu.com","name":"百度"},{"website":"google.com","name":"谷歌"}]')) asjson) test;

OK

www.baidu.com 百度

google.com 谷歌

Time taken:0.265 seconds, Fetched: 2 row(s)

3、自定义函数解析json对象

package com.laotou;

import org.apache.commons.lang3.StringUtils;

import org.apache.hadoop.hive.ql.exec.UDF;

import org.json.JSONException;

import org.json.JSONObject;

import org.json.JSONTokener;/**

*

* add jar jar/bdp_udf_demo-1.0.0.jar;

* create temporary function getJsonObject as 'com.laotou.JsonObjectParsing';

* Json对象解析UDF

* @Author:

* @Date: 2019/8/9*/

public classJsonObjectParsing extends UDF {public staticString evaluate(String jsonStr, String keyName) throws JSONException {if(StringUtils.isBlank(jsonStr) ||StringUtils.isBlank(keyName)){return null;

}

JSONObject jsonObject= new JSONObject(newJSONTokener(jsonStr));

Object objValue= jsonObject.get(keyName);if(objValue==null){return null;

}returnobjValue.toString();

}

}

3、1准备数据

3、2测试

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值