[Hive] 常用的 UDF 指令
當我們下指令詢問 Hive 的資料庫的時候,在比較進階的情況中,常常會遇到一些複雜的資料結構(struct),例如 array, map, array<struct>, map<int,struct> 等等。本篇的目的是整理一些常用的 Hive 的指令可以幫助我們處理複雜的資料結構。
Terms:
- UDF (User-Defined-Function): 用戶自己定義的函數,UDF 只能實現一進一出
- UDAF (User-Defined-Aggregation-Function): 用戶自定義聚合函數,實現類似 Sum, Avg, etc 等等的功能
- UDTF (User-Defined-Table-Generating-Funntion): 用戶自定義表格生成函數,用來解決一行輸入多行輸出的需求
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 or as a part of LATERAL VIEW. Explode 指令主要是將 array 或是 map 等等的 Collection 展開,以下展示一個例子,假設一個金融指數由多個公司組成如表格所示:
indexId | array<int> compositions |
1 | [100,200,300] |
2 | [400,500] |
經過以下
SELECT explode(compositions) AS compositionId FROM myTable;
我們可以得到:
compositionId |
100 |
200 |
300 |
400 |
500 |
Inline
定義:Explodes an array of structs to multiple rows. Returns a row-set with N columns (N = number of top level elements in the struct), one row per struct from the array. 基本上 inline 的功能跟 explode 是非常類似的,差別在於如果目標對象是 array<struct> 的話,inline 可以直接把 struct 裡面 N column 的值列成一個表,相反的 explode 只能夠用 struct 的方式呈現。
以下我們用實際的例子來呈現這兩個函式的差異:
select inline(array(struct('A',10,date '2019-01-01'),struct('B',20,date '2019-02-02')));
select explode(array(struct('A',10,date '2019-01-01'),struct('B',20,date '2019-02-02')));
以下是 inline 的結果:
col1 | col2 | col3 |
A | 10 | 2019-01-01 |
B | 20 | 2019-02-02 |
以下是 explode 的結果:
_2 |
struct(‘A’,10,date ‘2019-01-01’) |
struct(‘A’,20,date ‘2019-02-02’) |
Lateral View
上面介紹的 explode 與 inline 也可以配合 Lateral View 使用,使用 Lateral View 就屬於 UDTF 的範疇,可以產生一個新的表格,以同樣的表格為範例,使用
SELECT indexId, compositionId FROM myTable
LATERAL VIEW explode(compositions) compoTable AS compositionId;
SELECT indexId, compoTable.* FROM myTable
LATERAL VIEW inline(compositions) compoTable;
我們也可以得到一樣的結果,差別在於直接使用 explode 與 inline 不能夠在 SELECT 之後加入其他的訊息例如 indexId 等等,只會顯示 compositionId.
indexId | compositionId |
1 | 100 |
1 | 200 |
1 | 300 |
2 | 400 |
2 | 500 |
結論
Lateral View 通常與 UDTF 一起出現還解決 UDF 不允許在 SELECT 字串中加入其他行的問題。
參考資料
https://cwiki.apache.org/confluence/display/Hive/LanguageManual+UDF