OpenX JSON SerDe - Amazon Athena

OpenX JSON SerDe

Hive JSON SerDe와 마찬가지로 OpenX JSON을 사용하여 JSON 데이터를 처리할 수 있습니다. 데이터는 새 줄로 구분된 JSON 인코딩 텍스트의 한 줄 문자열로도 표시됩니다. Hive JSON SerDe와 마찬가지로 OpenX JSON SerDe는 map 또는 struct 키 이름에 중복 키를 허용하지 않습니다.

참고

SerDe는 각 JSON 문서가 레코드의 필드를 구분하는 줄 종료 문자가 없는 한 줄의 텍스트에 있을 것으로 예상합니다. JSON 텍스트가 가독성 좋게 꾸민 형식이면 테이블을 만든 후 쿼리하려고 할 때 HIVE_CURSOR_ERROR: 행이 유효한 JSON 객체가 아님(HIVE_CURSOR_ERROR: Row is not a valid JSON Object) 또는 HIVE_CURSOR_ERROR: JsonParseException: 예기치 않은 입력 종료: OBJECT의 닫기 마커 필요(HIVE_CURSOR_ERROR: JsonParseException: Unexpected end-of-input: expected close marker for OBJECT) 같은 오류 메시지가 나타날 수 있습니다. 자세한 내용은 GitHub의 OpenX SerDe 문서에서 JSON 데이터 파일을 참조하세요.

선택적 속성

Hive JSON SerDe와 달리 OpenX JSON SerDe에는 데이터의 불일치를 해결하는 데 유용한 다음과 같은 선택적 SerDe 속성이 있습니다.

ignore.malformed.json

선택 사항입니다. TRUE로 설정하면 형식이 잘못된 JSON 구문을 건너뛸 수 있습니다. 기본값은 FALSE입니다.

dots.in.keys

선택 사항입니다. 기본값은 FALSE입니다. TRUE로 설정하면 SerDe가 키 이름의 점을 밑줄로 바꿀 수 있습니다. 예를 들어 JSON 데이터 세트에 이름이 "a.b"인 키가 있을 경우 이 속성을 사용하여 Athena에서 열 이름이 "a_b"가 되도록 정의할 수 있습니다. 이 SerDe가 없으면 기본적으로 Athena는 열 이름에 점을 허용하지 않습니다.

case.insensitive

선택 사항입니다. 기본값은 TRUE입니다. TRUE로 설정하면 SerDe가 모든 대문자 열을 소문자로 변환합니다.

데이터에서 대/소문자를 구분하는 키 이름을 사용하려면 WITH SERDEPROPERTIES ("case.insensitive"= FALSE;)를 사용합니다. 그런 다음, 아직 모두 소문자가 아닌 모든 키에 대해 다음 구문을 사용하여 열 이름에서 속성 이름으로 매핑을 제공합니다.

ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("case.insensitive" = "FALSE", "mapping.userid" = "userId")

URLUrl와 같이 소문자로 동일한 두 개의 키가 있는 경우, 다음과 같은 오류가 발생할 수 있습니다.

HIVE_CURSOR_ERROR: 행이 유효한 JSON 객체가 아님 - JSONException: 중복 키 "url"

이 문제를 해결하려면 다음 예제와 같이 case.insensitive 속성을 FALSE로 설정하고 키를 다른 이름으로 매핑합니다.

ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("case.insensitive" = "FALSE", "mapping.url1" = "URL", "mapping.url2" = "Url")
매핑

선택 사항입니다. 열 이름을, 열 이름과 동일하지 않은 JSON 키에 매핑합니다. mapping 파라미터는 JSON 데이터에 키워드인 키가 있을 경우에 유용합니다. 예를 들어 timestamp라는 JSON 키가 있는 경우 다음 구문을 사용하여 키를 ts라는 열에 매핑합니다.

ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("mapping.ts" = "timestamp")
Hive 호환 이름에 콜론이 있는 중첩된 필드 이름 매핑

struct 내에 콜론이 있는 필드 이름이 있는 경우 mapping 속성을 사용하여 Hive 호환 이름에 필드를 매핑할 수 있습니다. 예를 들어 열 유형 정의에 my:struct:field:string이 포함된 경우 WITH SERDEPROPERTIES에 다음 항목을 포함하여 my_struct_field:string에 정의를 매핑할 수 있습니다.

("mapping.my_struct_field" = "my:struct:field")

다음 예제에서는 해당 CREATE TABLE 문을 보여줍니다.

CREATE EXTERNAL TABLE colon_nested_field ( item struct<my_struct_field:string>) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("mapping.my_struct_field" = "my:struct:field")

예제: 광고 데이터

다음 예제 DDL 문은 OpenX JSON SerDe를 사용하여 Hive JSON SerDe의 예제에 사용된 것과 동일한 샘플 온라인 광고 데이터를 기반으로 테이블을 생성합니다. LOCATION 절에서 myregion을, Athena를 실행하는 리전 식별자로 바꿉니다.

CREATE EXTERNAL TABLE impressions ( requestbegintime string, adid string, impressionId string, referrer string, useragent string, usercookie string, ip string, number string, processid string, browsercokie string, requestendtime string, timers struct< modellookup:string, requesttime:string>, threadid string, hostname string, sessionid string ) PARTITIONED BY (dt string) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' LOCATION 's3://myregion.elasticmapreduce/samples/hive-ads/tables/impressions';

예제: 중첩 JSON 역직렬화

JSON SerDes를 사용하여 더 복잡한 JSON 인코딩 데이터를 구문 분석 할 수 있습니다. 이를 위해서는 structarray 요소를 사용하여 중첩 구조를 나타내는 CREATE TABLE 문을 사용해야 합니다.

다음 예제에서는 중첩 구조가 있는 JSON 데이터로 Athena 테이블을 생성합니다. Athena에서 JSON 인코딩 데이터를 구문 분석하려면 각 JSON 문서가 한 줄당 하나씩 나열되며 줄 바꿈으로 구분되는지 확인합니다.

이 예제는 다음과 같은 구조의 JSON 인코딩 데이터를 가정합니다.

{ "DocId": "AWS", "User": { "Id": 1234, "Username": "bob1234", "Name": "Bob", "ShippingAddress": { "Address1": "123 Main St.", "Address2": null, "City": "Seattle", "State": "WA" }, "Orders": [ { "ItemId": 6789, "OrderDate": "11/11/2017" }, { "ItemId": 4352, "OrderDate": "12/12/2017" } ] } }

다음 CREATE TABLE 문은 Openx-JsonSerDestructarray 컬렉션 데이터 형식을 사용하여 개체 그룹을 설정할 수 있습니다. 각 JSON 문서는 한 줄당 하나씩 나열되며 줄 바꿈으로 구분이 됩니다. 오류를 방지하기 위해 쿼리되는 데이터에는 struct 또는 맵 키 이름의 중복 키가 포함되지 않습니다.

CREATE external TABLE complex_json ( docid string, `user` struct< id:INT, username:string, name:string, shippingaddress:struct< address1:string, address2:string, city:string, state:string >, orders:array< struct< itemid:INT, orderdate:string > > > ) ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' LOCATION 's3://mybucket/myjsondata/';