El SerDe JSON de OpenX - Amazon Athena

El SerDe JSON de OpenX

Al igual que el SerDe JSON de Hive, puede utilizar el JSON de OpenX para procesar datos JSON. Los datos también se representan como cadenas de una sola línea de texto con codificación JSON separadas por una línea nueva. Al igual que SerDe JSON de Hive, SerDe JSON de OpenX no permite claves duplicadas en map ni nombres de claves struct.

nota

El SerDe espera que cada documento JSON esté en una sola línea de texto sin caracteres de terminación de línea que separen los campos del registro. Si el texto JSON está en formato de impresión, puede recibir un mensaje de error como HIVE_CURSOR_ERROR: Row is not a valid JSON Object (HIVE_CURSOR_ERROR: la fila no es un objeto JSON válido) o HIVE_CURSOR_ERROR: JsonParseException: Unexpected end-of-input: expected close marker for OBJECT (HIVE_CURSOR_ERROR: JsonParseException: fin de entrada inesperado: marcador de cierre esperado para OBJECT) cuando intenta consultar la tabla después de crearla. Para obtener más información, consulte los Archivos de datos JSON en la documentación de OpenX SerDE en GitHub.

Propiedades opcionales

A diferencia del SerDe JSON de Hive, el SerDe JSON de OpenX también tiene las siguientes propiedades SerDe opcionales que pueden resultar útiles para solucionar incoherencias en los datos.

ignore.malformed.json

Opcional. Cuando se establece en TRUE, le permite omitir la sintaxis JSON con formato incorrecto. El valor predeterminado es FALSE.

dots.in.keys

Opcional. El valor predeterminado es FALSE. Cuando se establece en TRUE, permite que el SerDe sustituya los puntos en nombres de claves con guiones bajos. Por ejemplo, si el conjunto de datos de JSON contiene una clave con el nombre "a.b", puede utilizar esta propiedad para definir el nombre de la columna para que sea "a_b" en Athena. De forma predeterminada (sin este SerDe), Athena no permite puntos en los nombres de columnas.

case.insensitive

Opcional. El valor predeterminado es TRUE. Cuando se establece en TRUE, el SerDe convierte todas las columnas en mayúscula a minúscula.

Para utilizar nombres de clave que distinguen mayúsculas de minúsculas en los datos, utilice WITH SERDEPROPERTIES ("case.insensitive"= FALSE;). A continuación, para cada clave que no esté ya en minúsculas, proporcione un mapeo desde el nombre de la columna al nombre de la propiedad utilizando la siguiente sintaxis:

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

Si tiene dos claves como URL y Url que son iguales cuando se escriben en minúsculas, puede producirse un error como el siguiente:

HIVE_CURSOR_ERROR: Row is not a valid JSON Object - JSONException: Duplicate key "url"

Para resolver esto, establezca la propiedad case.insensitive en FALSE y asigne las claves a nombres diferentes, como en el ejemplo siguiente:

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

Opcional. Asigna nombres de columna a las claves JSON que no son idénticas a los nombres de las columnas. El parámetro mapping es útil cuando los datos JSON contienen claves que son palabras clave. Por ejemplo, si tiene una clave JSON denominada timestamp, utilice la siguiente sintaxis para mapear la clave a una columna denominada ts:

ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("mapping.ts" = "timestamp")
Asignación de nombres de campos anidados con dos puntos a nombres compatibles con Hive

Si tiene un nombre de campo con dos puntos dentro de una estructura struct, puede utilizar la propiedad mapping para asignar ese campo a un nombre compatible con Hive. Por ejemplo, si las definiciones de tipos de columna contienen my:struct:field:string, puede asignar la definición a my_struct_field:string incluyendo la siguiente entrada en WITH SERDEPROPERTIES:

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

En el siguiente ejemplo se muestra la instrucción CREATE TABLE correspondiente.

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")

Ejemplo: datos de publicidad

La instrucción DDL de ejemplo que se muestra a continuación, utiliza SerDe JSON de OpenX para crear una tabla en función de los mismos datos de publicidad en línea de ejemplo utilizados en el ejemplo para SerDe JSON de Hive. En la cláusula LOCATION, reemplace myregion por el identificador de región donde se ejecuta 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' with serdeproperties ( 'paths'='requestbegintime, adid, impressionid, referrer, useragent, usercookie, ip' ) LOCATION 's3://myregion.elasticmapreduce/samples/hive-ads/tables/impressions';

Ejemplo: deserialización de JSON anidado

Puede usar SerDes JSON para analizar datos codificados en JSON más complejos. Esto requiere el uso de instrucciones CREATE TABLE que utilizan elementos struct y array para representar estructuras anidadas.

En el ejemplo siguiente, se crea una tabla de Athena a partir de datos JSON que tienen estructuras anidadas. Para analizar los datos con codificación JSON en Athena, asegúrese de que cada documento JSON esté en su propia línea, separado por una nueva línea.

En este ejemplo se supone que los datos codificados en JSON tienen la siguiente estructura:

{ "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" } ] } }

La instrucción CREATE TABLE siguiente utiliza OpenX-JsonSerDe con los tipos de datos de colección struct y array para establecer grupos de objetos. Cada documento JSON se encuentra en su propia línea, separado de los demás por un carácter de nueva línea. Para evitar errores, los datos que se van a consultar no incluyen claves duplicadas en struct ni nombres de clave de mapeo.

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/';