1. 程式人生 > >hive載入json資料和解析json

hive載入json資料和解析json

事先說明,本人菜雞一隻,如果有說錯的地方,還請大家指出批評,多多包涵~

一、

今天記錄一下使用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,想記錄的東西記錄完了,祝大家春節快樂~

最後,本人菜雞一個,如果有說的不對的地方,還望各位大神指點迷津!!