HIVE 處理json結構數據


HIVE 處理json結構數據 

1 問題

寬表存儲數據,必然會面臨一個問題:一對多,數據是N倍的存儲。將會多占用N倍空間。而這些源數據入庫的時候,在文件中存放時,也可能使用json格式。

遇到這種情況,使用json_tuple來解析json數據是一個非常不錯的方法。如果只是查詢json中某一個Key的值,那么使用get_json_object是個更好的選擇。

2 知識點

 

2.1 lateral view

Lateral view 通常和split, explode等udtf一起封裝使用,它能夠將一行數據拆分成多行數據,在此基礎上可以對拆分后的數據進行聚合.

該函數的作用就是通過udtf相關函數把一行拆分成一行或者多行的結果進行聚合,產生一個支持別名表的虛擬表。

語法結構如下:

ATERAL VIEW udtf(expression) alias_table_name AS columns(',', columns)*

2.2 explode

explode 將數組、列表、MAP中每個元素轉換為同一列的不同行,可以理解為行轉列,處理的結果以表格的形式輸出。explode 只能處理數組(列表)或者map結構。 使用方法非常簡單:explode(數據或者列表或者MAP結構數據)。

比如數組: [1,2,3].可以轉換為

1
2
3

而map結構,比如字典:{'a':1,'b':2,'c':3} 可以轉換成:

a	1
b	2
c	3

各位可以執行下面兩個查詢語句塊,了解explode的效果:

select array(1,2,3);
select explode(array(1,2,3));

下面通過str_to_map1 來實現map結構

select str_to_map(concat('a:',1,'&b:',2,'&c:',3),'&',':');
select str_to_map(concat('a:',1,'^b:',2,'^c:',3),'\\^',':');
select explode(str_to_map(concat('a:',1,'&b:',2,'&c:',3),'&',':'));

2.3 json_tuple

json_tuple 從json格式數據中,通過指定的keys 來讀取相應的values. 讀取的結果以表格的形式輸出。語法結構如下:

使用方法如下:json_tuple(數據源,json中的key1,key2,….). 比如:

select json_tuple('{"a":1,"b":2,"c":3}','a','b');

3 示例

下面是將json數據轉換成表結構的示例。

  • 測試

    -- 建表
    drop table if exists jsontest;
    
    CREATE TABLE IF NOT EXISTS jsonTest
    (teacher_name varchar(10),
    major varchar(10),
    students_info string comment "學生信息"
    )
    comment "學生課程信息"
    row format serde 'org.apache.hive.hcatalog.data.JsonSerDe'
    LOCATION
      'hdfs://nameservice1/user/hive/warehouse/bigdata.db/jsontest';
    
    insert into jsontest values
    ('t1','語文','{"grade":1,"info":{"name":"xinzi","age":14,"sex":"M"}}|{"grade":3,"info":{"name":"lisi","age":14,"sex":"M"}}'),
    ('t2','maths','{"grade":2,"info":{"name":"zhangs","age":14,"sex":"F"}}')
    ;
    
    -- 查看已有數據
    select row_number() over() , a.* from jsontest a;
    
    
    
    -- 創建視圖
    drop view if exists v_jsontest;
    create view if not exists v_jsontest
    as
    select teacher_name,major,a.grade,b.name,b.age,b.gender from jsontest lateral view explode(split(students_info,'\\|')) stabcdefghi as stin
    lateral view json_tuple(stin,'grade','info') a as grade,info
    lateral view json_tuple(a.info,'name','age','sex') b as name,age,gender;
    
  • 原表數據

    hive> select * from jsontest;
    OK
    t1	語文	{"grade":1,"info":{"name":"xinzi","age":14,"sex":"M"}}|{"grade":3,"info":{"name":"lisi","age":14,"sex":"M"}}
    t2	maths	{"grade":2,"info":{"name":"zhangs","age":14,"sex":"F"}}
    Time taken: 0.054 seconds, Fetched: 2 row(s)
    
  • 轉換后結果

    hive> select * from v_jsontest;
    ..........
    OK
    t1	語文	1	xinzi	14	M
    t1	語文	3	lisi	14	M
    t2	maths	2	zhangs	14	F
    Time taken: 12.933 seconds, Fetched: 3 row(s)
    

Footnotes:

1

關於map,可以通過函數str_to_map來實現,也可以在建表時定義。這里使用str_to_map 來進行測試. str_to_map(字符串參數, 分隔符1, 分隔符2),使用兩個分隔符將文本拆分為鍵值對。 分隔符1將文本分成K-V對,分隔符2分割每個K-V對。對於分隔符1默認分隔符是 ',',對於分隔符2默認分隔符是 '='。

Author: halberd.lee

Created: 2020-04-09 Thu 13:48

Validate


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM