OpenX JSON SerDe
Come Hive JSON SerDe, per elaborare i dati JSON puoi usare OpenX JSON. Questi dati sono rappresentati come stringhe su una sola riga di testo con codifica JSON separati da una nuova riga. Come il SerDE JSON Hive, il SerDe JSON OpenX non consente chiavi duplicate nei nomi delle chiavi in map o struct.
Considerazioni e limitazioni
-
Quando si utilizza OpenX JSON SerDe, il numero di risultati e i relativi valori possono essere non deterministici. I risultati possono contenere più righe del previsto, meno righe del previsto o valori nulli imprevisti quando non sono presenti nei dati sottostanti. Per risolvere il problema, utilizzare Hive JSON SerDe o riscrivere i dati in un altro tipo di formato di file.
-
SerDe prevede che ogni documento JSON sia su una singola riga di testo senza caratteri di terminazione riga che separano i campi nel registro. Se il testo JSON è formattato, quando si prova a eseguire una query sulla tabella dopo averla creata, è possibile che venga visualizzato un messaggio di errore come
HIVE_CURSOR_ERROR: Row is not a valid JSON Object (HIVE_CURSOR_ERROR: la riga non è un oggetto JSON valido)oHIVE_CURSOR_ERROR: JsonParseException: Unexpected end-of-input: expected close marker for OBJECT(HIVE_CURSOR_ERROR: JSONParseException: fine di input imprevisto: indicatore di chiusura previsto per OBJECT).Per ulteriori informazioni, consulta File di dati JSON
nella documentazione OpenX SerDe su GitHub.
Proprietà facoltative
A differenza del SerDe JSON Hive, il SerDe JSON OpenX dispone anche delle seguenti proprietà SerDe opzionali che possono essere utili per risolvere le incongruenze nei dati.
- usa.null.for.invalid.data
-
Facoltativo. Il valore predefinito è
FALSE. Se impostato suTRUE, SerDe lo utilizzaNULLper i valori di colonna che non sono riusciti a deserializzare nel tipo di colonna definito dallo schema della tabella.Importante
L'impostazione
use.null.for.invalid.datasuTRUEpuò causare risultati errati o imprevisti perché i valoriNULLsostituiscono i dati non validi nelle colonne con mancate corrispondenze dello schema. Si consiglia di correggere i dati nei file o nello schema della tabella anziché abilitare questa proprietà. Quando si abilita questa proprietà, le query non avranno esito negativo su dati non validi, il che potrebbe impedire di scoprire problemi di qualità dei dati. - ignore.malformed.json
-
Facoltativo. Quando è impostata su
TRUE, consente di saltare la sintassi JSON errata. Il valore predefinito èFALSE. - dots.in.keys
-
Facoltativo. Il valore predefinito è
FALSE. Quando è impostata suTRUE, consente al SerDe di sostituire i punti nei nomi di chiavi con caratteri di sottolineatura. Ad esempio, se il set di dati JSON contiene una chiave denominata"a.b", è possibile usare questa proprietà per definire il nome della colonna come"a_b"in Athena. Per impostazione predefinita (senza questo SerDe), Athena non consente l'uso di punti nei nomi di colonna. - case.insensitive
-
Facoltativo. Il valore predefinito è
TRUE. Quando è impostata suTRUE, il SerDe converte in minuscolo tutte le colonne in maiuscolo.Per utilizzare i nomi di chiavi con distinzione tra maiuscole e minuscole nei dati, utilizzare
WITH SERDEPROPERTIES ("case.insensitive"= FALSE;). Quindi, per ogni chiave che non è già composta da sole minuscole, fornire un mapping dal nome della colonna al nome della proprietà utilizzando la sintassi seguente:ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("case.insensitive" = "FALSE", "mapping.userid" = "userId")Se hai due chiavi tipo
URLeUrlche sono uguali quando sono in minuscolo, può verificarsi un errore come il seguente:HIVE_CURSOR_ERROR: la riga non è un oggetto JSON valido - JSONException: "url" chiave duplicato"Per risolvere questo problema, impostare la proprietà
case.insensitivesuFALSEe mappare le chiavi a nomi diversi, come nell'esempio seguente:ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("case.insensitive" = "FALSE", "mapping.url1" = "URL", "mapping.url2" = "Url") - mappatura
-
Facoltativo. Mappa i nomi di colonna a chiavi JSON che non sono identiche ai nomi di colonna. Il parametro
mappingè utile quando i dati JSON contengono chiavi che sono parole chiave. Ad esempio, se si dispone di una chiave JSON denominatatimestamp, utilizzare la sintassi seguente per mappare la chiave a una colonna denominatats:ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("mapping.ts" = "timestamp")Mappatura dei nomi dei campi annidati con due punti a nomi compatibili con Hive
Se hai il nome di un campo con due punti all'interno di uno
struct, puoi utilizzare la proprietàmappingper mappare il campo a un nome compatibile con Hive. Ad esempio, se le definizioni dei tipi di colonna contengonomy:struct:field:string, puoi mappare la definizione amy_struct_field:stringincludendo la seguente voce inWITH SERDEPROPERTIES:("mapping.my_struct_field" = "my:struct:field")L'esempio seguente mostra l'istruzione
CREATE TABLEcorrispondente.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")
Esempio: dati pubblicitari
L'istruzione DDL di esempio seguente utilizza il SerDe JSON OpenX per creare una tabella basata sugli stessi dati pubblicitari online di esempio utilizzati nell'esempio per SerDe JSON Hive. Nella clausola LOCATION sostituire myregion con l'identificatore Regione in cui si esegue 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://amzn-s3-demo-bucket.elasticmapreduce/samples/hive-ads/tables/impressions';
Esempio di deserializzazione di un JSON nidificato
È possibile utilizzare i SerDe JSON per analizzare dati codificati JSON più complessi. Ciò richiede l'utilizzo di istruzioni CREATE TABLE che utilizzino elementi struct e array per rappresentare strutture nidificate.
Nell'esempio seguente viene creata una tabella Athena dai dati JSON con strutture nidificate. Il file ha la struttura seguente:
{
"DocId": "AWS",
"User": {
"Id": 1234,
"Username": "carlos_salazar",
"Name": "Carlos",
"ShippingAddress": {
"Address1": "123 Main St.",
"Address2": null,
"City": "Anytown",
"State": "CA"
},
"Orders": [
{
"ItemId": 6789,
"OrderDate": "11/11/2022"
},
{
"ItemId": 4352,
"OrderDate": "12/12/2022"
}
]
}
}
Ricorda che OpenX SerDe prevede che ogni record JSON sia su una singola riga di testo. Se archiviati in Amazon S3, tutti i dati dell'esempio precedente devono trovarsi su un'unica riga, in questo modo:
{"DocId":"AWS","User":{"Id":1234,"Username":"carlos_salazar","Name":"Carlos","ShippingAddress" ...
L'istruzione CREATE TABLE seguente utilizza OpenX-JsonSerDestruct e array per stabilire gruppi di oggetti.
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://amzn-s3-demo-bucket/myjsondata/';
Per eseguire query sulla tabella, utilizzare una SELECT istruzione come la seguente.
SELECT user.name as Name, user.shippingaddress.address1 as Address, user.shippingaddress.city as City, o.itemid as Item_ID, o.orderdate as Order_date FROM complex_json, UNNEST(user.orders) as temp_table (o)
Per accedere ai campi di dati all'interno delle strutture, la query di esempio utilizza la notazione a punti (ad esempio,user.name). Per accedere ai dati all'interno di una matrice di strutture (come nel orders campo), puoi usare la funzione. UNNEST La UNNEST funzione appiattisce l'array in una tabella temporanea (in questo caso chiamata). o Ciò consente di utilizzare la notazione a punti come si fa con le strutture per accedere agli elementi dell'array non annidati (ad esempio,). o.itemid Il nome temp_table, usato nell'esempio a scopo illustrativo, è spesso abbreviato in. t
Nella tabella seguente sono riportati i risultati di esempio.
| # | Nome | Indirizzo | City | id_articolo | Data_ordine |
|---|---|---|---|---|---|
| 1 | Carlos | 123 Main St. | Qualsiasi città | 6789 | 11/11/2022 |
| 2 | Carlos | 123 Main St. | Qualsiasi città | 4352 | 12/12/2022 |