5.hive解析json数据

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

在介绍如何处理之前,我们先来了解下 Hive 内置的 explode 函数,官方的解释是: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一起使用。光看文字描述很不直观,咱们来看看几个例子吧。

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

OK

A

B

C

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

 

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

OK

A 10

B 20

C 30

相信不需要我描述大家就能看明白这个函数的意义。大家可能会问,这个函数和我们解析 Json 数组有毛关系啊。其实有关系,我们其实可以使用这个函数将 Json 数组里面的元素按照一行一行的形式输出。根据这些已有的知识,我们可以写出以下的 SQL 语句:

hive (default)> SELECT explode(split(regexp_replace(regexp_replace('[{"website":"www.iteblog.com","name":"过往记忆"},{"website":"carbondata.iteblog.com","name":"carbondata 中文文档"}]', '{','\\}\\;\\{'),'\\[|\\]',''),'\\;'));

OK

{"website":"www.iteblog.com","name":"过往记忆"}

{"website":"carbondata.iteblog.com","name":"carbondata 中文文档"}

现在我们已经能正确的解析 Json 数据了。

你现在肯定不知道上面一堆的 SQL 是啥含义,这里我来一步一步的解释。

 

  • explode 函数只能接收数组或 map 类型的数据,而 split 函数生成的结果就是数组;
  • 第一个 regexp_replace 的作用是将 Json 数组元素之间的逗号换成分号,所以使用完这个函数之后,[{"website":"www.iteblog.com","name":"过往记忆"},{"website":"carbondata.iteblog.com","name":"carbondata 中文文档"}] 会变成[{"website":"www.iteblog.com","name":"过往记忆"};{"website":"carbondata.iteblog.com","name":"carbondata 中文文档"}]
  • 第二个 regexp_replace 的作用是将 Json 数组两边的中括号去掉,所以使用完这个函数之后,[{"website":"www.iteblog.com","name":"过往记忆"},{"website":"carbondata.iteblog.com","name":"carbondata 中文文档"}] 会变成{"website":"www.iteblog.com","name":"过往记忆"},{"website":"carbondata.iteblog.com","name":"carbondata 中文文档"}

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

hive (default)> select json_tuple(json, 'website', 'name') from (SELECT explode(split(regexp_replace(regexp_replace('[{"website":"www.iteblog.com","name":"过往记忆"},{"website":"carbondateblog.com","name":"carbondata 中文文档"}]', '\\}\\,\\{','\\}\\;\\{'),'\\[|\\]',''),'\\;')) as json) iteblog;

OK

www.iteblog.com 过往记忆

carbondata.iteblog.com  carbondata 中文文档

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

自定义函数解析 Json 数组

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

package com.iteblog.udf.json;

 

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<String> evaluate(String jsonString) {

        if (jsonString == null) {

            return null;

        }

        try {

            JSONArray extractObject = new JSONArray(jsonString);

            ArrayList<String> result = new ArrayList<String>();

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

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

            }

            return result;

        } catch (JSONException e) {

            return null;

        } catch (NumberFormatException e) {

            return null;

        }

    }

}

上面的代码逻辑很简单,我就不介绍了。将上面的代码进行编译打包,假设打包完的 jar 包名称为 iteblog.jar,然后我们就可以如下使用这个函数了。

hive (default)> add jar /home/iteblog/iteblog.jar;

Added [/home/iteblog/iteblog.jar] to class path

Added resources: [/home/iteblog/iteblog.jar]

hive (default)> create temporary function json_array as 'com.iteblog.udf.json.UDFJsonAsArray';

OK

Time taken: 0.013 seconds

hive (default)>

              > select explode(json_array('[{"website":"www.iteblog.com","name":"过往记忆"},{"website":"carbondata.iteblog.com","name":"carbondata 中文文档"}]'));

OK

{"website":"www.iteblog.com","name":"过往记忆"}

{"website":"carbondata.iteblog.com","name":"carbondata 中文文档"}

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

 

hive (default)> select json_tuple(json, 'website', 'name') from (SELECT explode(json_array('[{"website":"www.iteblog.com","name":"过往记忆"},{"website":"carbondata.iteblog.com","name":"carbta 中文文档"}]')) as json) iteblog;

OK

www.iteblog.com 过往记忆

carbondata.iteblog.com  carbondata 中文文档

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

这个结果和上面使用 Hive 内置的函数结果一致。当然,你还可以实现其他的 UDF,逻辑和这个类似,就不再介绍了。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值