티스토리 뷰
hive 의 udf 로 사용하다보면 아쉬운점이 많은데, brickhouse 의 UDF 를 쓰면 가려운 부분을 많이 긁어줘서 편하게 로직을 만들수 있다. 여러 케이스의 udf 가 있지만, 여기서는 json 관련 udf 의 샘플과 예시를 적어두고자 한다. 편의상 add jar 는 되어있다고 가정하겠다.
https://github.com/klout/brickhouse
json 함수는 아래 코드 위치에 존재하는 udf 를 의미하며 간단한 설명과 예시를 안내한다.
https://github.com/klout/brickhouse/tree/master/src/main/java/brickhouse/udf/json
0. hive 의 json 기본 함수
brickhouse 가 아닌, hive 에 기본포함된 json 함수의 경우 마이크로소프트의 azure 문서에 장 저리되어있다.
크게보면 2개의 udf 를 사용할 수 있으며, 좀더 복잡한 json 표현을 다루려면 brickhouse 에서 다루는 함수를 사용하자.
https://learn.microsoft.com/ko-kr/azure/hdinsight/hadoop/using-json-in-hive
- get_json_object
- json_tuple
1. to_json
struct 타입의값을 문자열 형태의 json 으로 변환한다. 데이터를 text 포맷으로 떨궈낼때 json 문자열로 리턴하면 유용할때가 존재한다. 다음 예시는 named_struct 로 표현한걸 json 문자열로 변환해서, get_json_onject 로 추출하는걸 테스트한 예시이다.
(사실 이런식으로 쓸일은 없겠지만)
beeline> CREATE TEMPORARY FUNCTION to_json AS 'brickhouse.udf.json.ToJsonUDF';
No rows affected (0.023 seconds)
beeline> select get_json_object ( to_json( named_struct('name' , 'gildong', 'age', 18) ) , '$.name');
+----------+
| _c0 |
+----------+
| gildong |
+----------+
1 row selected (0.085 seconds)
2. from_json
to_json 과 반대로 문자열 형태로 되어있는 데이터를 struct 형태의 데이터 타입으로 리턴하는 함수이다.
단, struct 의 타입을 판단해야하기 때문인지, named_struct 로 변환할 필드를 나열해야 사용가능하다.
이 특성을 이용하면 json 에서 필요한 key 값만 추출한 named_struct 타입으로 바꾸는것도 가능할것이다.
beeline> CREATE TEMPORARY FUNCTION from_json AS 'brickhouse.udf.json.FromJsonUDF';
beeline> select from_json(f, named_struct('name', '', 'age', 0)) from (
select '{"name": "gildong", "age": 18, "address": "seoul"}' as f
UNION ALL
select '{"name": "tochi", "age": 20, "address": "busan"}' as f
) t;
+------------------------------+
| _c0 |
+------------------------------+
| {"name":"gildong","age":18} |
| {"name":"tochi","age":20} |
+------------------------------+
2 rows selected (0.086 seconds)
3. to_camel_case
json 문자열의 key 값을 카멜케이스로 변환해 주는 기능이다. dbms 에서는 일반적으로 필드명에 대소문자 구분을 안하다보니 스네이크케이스를 많이 쓰는데 이걸 카멜케이스로 바꾸고 싶을때 사용하는 함수이다. 쉽게 생각해서 json 의 key 를 field_name 과 같은걸 fieldName 형태로 바꿔준다고 생각하면 된다.
beeline> CREATE TEMPORARY FUNCTION to_camel_case AS 'brickhouse.udf.json.ConvertToCamelCaseUDF';
beeline> select '{"My_Name": "gildong", "My_Age": 18}';
+---------------------------------------+
| _c0 |
+---------------------------------------+
| {"My_Name": "gildong", "My_Age": 18} |
+---------------------------------------+
1 row selected (0.084 seconds)
beeline> select to_camel_case('{"My_Name": "gildong", "My_Age": 18}');
+-------------------------------------+
| _c0 |
+-------------------------------------+
| {"myName": "gildong", "myAge": 18} |
+-------------------------------------+
1 row selected (0.085 seconds)
4. from_camel_case
json 문자열의 키값을 카멜케이스에서 스네이크 케이스로 변경해주는 기능이다. (즉, to_camel_case 의 반대)
beeline> CREATE TEMPORARY FUNCTION from_camel_case AS 'brickhouse.udf.json.ConvertFromCamelCaseUDF';
beeline> select '{"myName": "gildong", "myAge": 18}';
+-------------------------------------+
| _c0 |
+-------------------------------------+
| {"myName": "gildong", "myAge": 18} |
+-------------------------------------+
1 row selected (0.178 seconds)
beeline> select from_camel_case('{"myName": "gildong", "myAge": 18}');
+---------------------------------------+
| _c0 |
+---------------------------------------+
| {"my_name": "gildong", "my_age": 18} |
+---------------------------------------+
1 row selected (0.117 seconds)
5. json_map (이상함)
json 문자열을 map 타입으로 리턴하는 기능이다. 그런데 버그가 있는건지 문자열 타입을 미지원하는것인지 숫자만 제대로 인지하고 있다.
beeline> CREATE TEMPORARY FUNCTION json_map AS 'brickhouse.udf.json.JsonMapUDF';
beeline> select '{"name": "gildong", "age": 18}';
+---------------------------------+
| _c0 |
+---------------------------------+
| {"name": "gildong", "age": 18} |
+---------------------------------+
1 row selected (0.528 seconds)
beeline> select json_map('{"name": "gildong", "age": 18}');
+--------------------------+
| _c0 |
+--------------------------+
| {"name":0.0,"age":18.0} | <--- name 값이 gildong 이 아니라 0.0 으로 잡힘
+--------------------------+
1 row selected (0.103 seconds)
beeline> select json_map('{"name": "gildong", "age": 18}')["age"];
+-------+
| _c0 |
+-------+
| 18.0 |
+-------+
1 row selected (0.085 seconds)
6. json_split
json 문자열이 array 로 되어있을때, 데이터를 풀어서 데이터를 리턴한다.
쉽게 생각해서 string 형태의 json 값을 array<string> 타입으로 리턴한다고 보면된다.
beeline> CREATE TEMPORARY FUNCTION json_split AS 'brickhouse.udf.json.JsonSplitUDF';
beeline> select json_split('[{"name": "gildong", "age": 18}, {"name": "haha", "age": 1}]');
+----------------------------------------------------+
| _c0 |
+----------------------------------------------------+
| ["{\"name\":\"gildong\",\"age\":18}","{\"name\":\"haha\",\"age\":1}"] |
+----------------------------------------------------+
1 row selected (0.079 seconds)
beeline> select json_split('[{"name": "gildong", "age": 18}, {"name": "haha", "age": 1}]')[0]
+------------------------------+
| _c0 |
+------------------------------+
| {"name":"gildong","age":18} |
+------------------------------+
1 row selected (0.084 seconds)
마무리
brickhouse 에는 json 다루는 함수 말고도 다양한 함수가 존재하는데, 다른 함수가 궁금하면 다른글을 참고해보자
2023.12.29 - [데이터처리/Hive] - [HIVE] Array 를 다루는 함수 정리 (UDF) - 기본 + brickhouse
'데이터처리 > Hive' 카테고리의 다른 글
[HIVE] hive 4.x 버전에 추가된 array 함수 8개 : 예제 포함 (0) | 2024.01.26 |
---|---|
[HIVE] brickhouse UDF 사용예제 - timeseries (1) | 2024.01.19 |
[HIVE] Array 를 다루는 함수 정리 (UDF) - 기본 + brickhouse (0) | 2023.12.29 |
[HIVE] 타입별 test 용 데이터 표현 방법 - map/struct/array (0) | 2023.12.12 |
[HIVE] external table 이름 변경 후 location 까지 변경하는 방법 - 파티션 포함 (0) | 2023.12.01 |