2018年02月28日 13:27:58 阅读数:3472 标签: json 更多
个人分类: hive
事先说明,本人菜鸡一只,如果有说错的地方,还请大家指出批评,多多包涵~
一、
今天记录一下使用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对象),所以看情况选择这两个方法去使用。
OK,想记录的东西记录完了,祝大家春节快乐~
最后,本人菜鸡一个,如果有说的不对的地方,还望各位大神指点迷津!!