티스토리 뷰

반응형

hive 의 udf 로 사용하다보면 아쉬운점이 많은데, brickhouse 의 UDF 를 쓰면 가려운 부분을 많이 긁어줘서 편하게 로직을 만들수 있다. 여러 케이스의 udf 가 있지만, 여기서는 json 관련 udf 의 샘플과 예시를 적어두고자 한다. 편의상 add jar 는 되어있다고 가정하겠다.

https://github.com/klout/brickhouse

 

GitHub - klout/brickhouse: Hive UDF's for the data warehouse

Hive UDF's for the data warehouse. Contribute to klout/brickhouse development by creating an account on GitHub.

github.com

 

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

반응형
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2025/01   »
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
글 보관함