【Hive】hive加载json数据和解析json(一)

本文主要还是介绍hive中函数的解析json的函数get_json_object()和json_tuple()的使用,如果想通过serde直接加载hive数据,请看第二篇!

【Hive】hive加载json数据和解析json(二):https://blog.csdn.net/lsr40/article/details/103020021

 

一、

今天记录一下使用hive怎么加载json格式的数据,对于json格式,就不多做更多说明了,测试的数据是spark的example里面的people.json,数据很少,但是说明情况足矣。

先给出官网地址:https://cwiki.apache.org/confluence/display/Hive/LanguageManual%20DDL#LanguageManualDDL-JSON

数据是这样的:

 

{"name":"Michael"}

{"name":"Andy", "age":30}

{"name":"Justin", "age":19}

一个大括号是一个对象(一行数据),然后Michael这位小朋友age字段是缺失的。

1、接着开启hive,创建表(建表语句如下):

 create table spark_people_json( 

`name` string,

`age`   int)

ROW FORMAT SERDE 'org.apache.hive.hcatalog.data.JsonSerDe'

STORED AS TEXTFILE;

2、但是这样直接使用JsonSerDe类,是会报错的,因为这个类并没有在初始化的时候加载到环境中

报错如下:

FAILED: Execution Error, return code 1 from org.apache.hadoop.hive.ql.exec.DDLTask. Cannot validate serde: org.apache.hive.hcatalog.data.JsonSerDe

3、因此先执行

ADD JAR ${HIVE_HOME}/hcatalog/share/hcatalog/hive-hcatalog-core-0.13.1-cdh5.3.6.jar

注:${HIVE_HOME}是hive的根目录,自己对应替换,还有本文测试的hive是hive-0.13.1-cdh5.3.6这个版本的,不同版本这个jar可能会有点路径上的区别,但是理论上是能找得到的!实在不行可以在中央仓库找找:http://mvnrepository.com/

4、在环境中添加了jar之后,接着创建表,就可以成功创建了(hive加载不同的数据使用的分隔符可能是不同的类,可以研究下这些类是怎么写的,就可以写出符合自己需求的分割类,然后打成jar包上传服务器,add就可以了,不过大多数通用的数据类型都是有对应的别人写好的类的,例如csv/tsv的就叫org.apache.hadoop.hive.serde2.OpenCSVSerde)

5、创建好表之后,就load数据

load  data local inpath '/datas/people.json' into table spark_people_json;

6、最后进行select得到结果

7、字段缺失的值为NULL

 

二、

第二个是记录下如果只是某个字段为json,想要获取里面的某个值怎么操作?

有这么两个函数:get_json_object()和json_tuple()

1、get_json_object()

get_json_object函数第一个参数填写json对象变量,第二个参数使用$表示json变量标识,然后用 . 或 [] 读取对象或数组;

什么意思?

1、就是这样:

select get_json_object('{"shop":{"book":[{"price":43.3,"type":"art"},{"price":30,"type":"technology"}],"clothes":{"price":19.951,"type":"shirt"}},"name":"jane","age":"23"}', '$.shop.book[0].type')  

结果:

2、如果json简单,可以直接这样使用:

select get_json_object('{"name":"jack","server":"www.qq.com"}','$.server')

结果:

3、但是问题来了每次只能查一个字段

不信你可以试试:select get_json_object('{"name":"jack","server":"www.qq.com"}','$.server','$.name')

结果:

大概来说,意思是这个方法,只能接受两个参数,多的不行,那么就导致我们对同一个json数据想要查看多个值,只能多写几个get_json_object,比较麻烦,所以另一个方法就派上了用场。

4、json_tuple

使用方法:

select json_tuple('{"name":"jack","server":"www.qq.com"}','server','name')

结果:

5、但是缺点就是对于复杂的嵌套的json,就操作不了了(就是说使用不了".",“[]”这种符号来操作json对象),所以看情况选择这两个方法去使用。