티스토리 뷰

반응형

hive 에서 array 를 다루는 함수가 기본적으로 너무 없었다. 배열크기를 찾는 size, 배열에 포함여부를 찾는 array_contains, 그리고 배열을 정렬해주는 sort_array 정도만 존재했다. 사실상 explode() 처리후 다시 collect_list() 로 묶어서 처리하라는 말인데...

문제는 2개의 필드를 explode() 해야할 경우 이게 참 껄끄러운 문제가 많고 아쉬운점이 많았다.

https://cwiki.apache.org/confluence/display/hive/languagemanual+udf#LanguageManualUDF-CollectionFunctions

Hive 4.x 추가된 Array 함수

hive 4.x 버전대부터 꽤 많은 UDF 가 추가되어있다. (근데 왜 hive wiki 에 업데이트가 안되어있는가)

정말 우연히 관련 자료를 서칭하다가 array_remove 기능을 찾다가 얻어걸린 케이스였다.

https://github.com/apache/hive/blob/branch-4.0/ql/src/java/org/apache/hadoop/hive/ql/exec/FunctionRegistry.java

hive 4.x 에는 기존에 없던 array 관련 함수가 많이 늘었다.

 

1. array_min / array_max

array 에서 가장 작은 아이템 혹은 가장 큰 아이템을 리턴한다

beeline> select array_min( array(3,1,3,4) );
+------+
| _c0  |
+------+
| 1    |
+------+
1 row selected (0.092 seconds)

beeline> select array_max( array(3,1,3,4) );
+------+
| _c0  |
+------+
| 4    |
+------+
1 row selected (0.115 seconds)

 

2 array_distinct

array 에서 중복을 제거한 배열을 리턴한다.

beeline> select array_distinct( array(3,1,3,4) );
+----------+
|   _c0    |
+----------+
| [3,1,4]  |
+----------+
1 row selected (0.088 seconds)

 

3. array_join

array 를 특정 구분자를 붙여서 하나의 문자열로 리턴한다.

beeline> select array_join( array(3,1,3,4), "-" );
+----------+
|   _c0    |
+----------+
| 3-1-3-4  |
+----------+
1 row selected (0.075 seconds)

 

4. array_slice

array 를 index 위치에서 N 개의 길이만큼 데이터를 잘라낸 배열을 리턴한다. (index 는 0에서 시작)

만약, 범위를 벗어난 index 를 사용하면 empty array 를 리턴한다.

beeline> select array_slice( array(3,1,6,4,5),0 , 2);
+--------+
|  _c0   |
+--------+
| [3,1]  |
+--------+
1 row selected (0.096 seconds)

beeline> select array_slice( array(3,1,6,4,5), 1 , 2);
+--------+
|  _c0   |
+--------+
| [1,6]  |
+--------+
1 row selected (0.083 seconds)

beeline> select array_slice( array(3,1,6,4,5), 2 , 2);
+--------+
|  _c0   |
+--------+
| [6,4]  |
+--------+
1 row selected (0.08 seconds)

beeline> select array_slice( array(3,1,6,4,5), 10 , 2);
+------+
| _c0  |
+------+
| []   |
+------+
1 row selected (0.082 seconds)

 

5. array_except

첫번째 인자의 배열에서 두번째 배열을 제거한 결과를 리턴한다. 쉽게 생각해서 array 의 차집합이라고 생각하면 된다.

두번재 인자를 1개의 아이템만 선언하면 사실상 array_remove 와 동일한 동작을 한다고 생각하면 쉽다.

beeline> select array_except( array(1,2,3), array(1,3,4));
+------+
| _c0  |
+------+
| [2]  |
+------+
1 row selected (0.082 seconds)

beeline> select array_except( array(1,2,3), array(2));
+--------+
|  _c0   |
+--------+
| [1,3]  |
+--------+
1 row selected (0.077 seconds)

 

6. array_intersect

array 의 교집합을 리턴한다. 이때 중복된 값은 제거된다. 교집합 대상이 없다면 emtpy array 를 리턴한다.

beeline> select array_intersect( array(1,2,3), array(2,2,3) );
+--------+
|  _c0   |
+--------+
| [2,3]  |
+--------+
1 row selected (0.083 seconds)

beeline> select array_intersect( array(1,2,3), array(4,5,6) );
+------+
| _c0  |
+------+
| []   |
+------+
1 row selected (0.079 seconds)

 

 

7. array_union

array 의 합집합을 리턴한다. 이때, 중복되는 아이템은 제거된다.

beeline> select array_union( array(1,2,3), array(2,2,3,4) );
+------------+
|    _c0     |
+------------+
| [1,2,3,4]  |
+------------+
1 row selected (0.078 seconds)

 

8. array_remove

array 에서 특정 아이템을 제거한다. 

beeline> select array_remove( array(3,2,1, 4), 2 );
+----------+
|   _c0    |
+----------+
| [3,1,4]  |
+----------+
1 row selected (0.082 seconds)

 

마치며

사실 hive 의 기본 udf 의 기능이 조금 아쉬운점이 많았고, 이를 보완하기위해서 많이 써오던것이 brickhouse 라는 udf 모음 라이브러리였다. 하지만 몇년전 부터 유지보수가 안되는 문제가 있고 hive 가 버전업되면서 일부 udf 는 오류도 나는 문제가 있었는데 정말 반가운 소식이다. 더 다양한 기능과 udf 를 사용하고자 한다면 아래와 같은 함수를 써보기보다는 hive 버전을 업그레이드 해보는건 어떨까?

brickhouse 는 hive 의 udf 를 확장하기위해 참 좋은 라이브러리지만 관리안된지 오래되었다

물론 azure 같은 클라우드형 서비스의 경우 아직 hive 3.1.0 인걸 보면 현실적으로 버전업이 쉽진 않을수 있겠지만, 적어도 udf 를 맨땅에서 만들 필요는 없을것 같다. (apache hive 의 4.x 의 코드를 참고해서 만들면 될테니)

 

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/10   »
1 2 3 4 5
6 7 8 9 10 11 12
13 14 15 16 17 18 19
20 21 22 23 24 25 26
27 28 29 30 31
글 보관함