티스토리 뷰
hive 에서 array 를 다루는 함수가 기본적으로 너무 없었다. 배열크기를 찾는 size, 배열에 포함여부를 찾는 array_contains, 그리고 배열을 정렬해주는 sort_array 정도만 존재했다. 사실상 explode() 처리후 다시 collect_list() 로 묶어서 처리하라는 말인데...
문제는 2개의 필드를 explode() 해야할 경우 이게 참 껄끄러운 문제가 많고 아쉬운점이 많았다.
Hive 4.x 추가된 Array 함수
hive 4.x 버전대부터 꽤 많은 UDF 가 추가되어있다. (근데 왜 hive wiki 에 업데이트가 안되어있는가)
정말 우연히 관련 자료를 서칭하다가 array_remove 기능을 찾다가 얻어걸린 케이스였다.
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 버전을 업그레이드 해보는건 어떨까?
물론 azure 같은 클라우드형 서비스의 경우 아직 hive 3.1.0 인걸 보면 현실적으로 버전업이 쉽진 않을수 있겠지만, 적어도 udf 를 맨땅에서 만들 필요는 없을것 같다. (apache hive 의 4.x 의 코드를 참고해서 만들면 될테니)
'데이터처리 > Hive' 카테고리의 다른 글
[HIVE] Struct 타입의 일부값만 변경하는 UDF : set_value (2) | 2024.02.07 |
---|---|
[HIVE] hive 4.x 에 있는 array udf 추출버전 jar - hive 3.x 버전에서 활용하기 (0) | 2024.01.29 |
[HIVE] brickhouse UDF 사용예제 - timeseries (1) | 2024.01.19 |
[HIVE] JSON 을 다루는 함수 설명 & 예시 - brickhouse UDF (0) | 2024.01.18 |
[HIVE] Array 를 다루는 함수 정리 (UDF) - 기본 + brickhouse (0) | 2023.12.29 |