OpenX JSON SerDe - Amazon Athena

Die vorliegende Übersetzung wurde maschinell erstellt. Im Falle eines Konflikts oder eines Widerspruchs zwischen dieser übersetzten Fassung und der englischen Fassung (einschließlich infolge von Verzögerungen bei der Übersetzung) ist die englische Fassung maßgeblich.

OpenX JSON SerDe

Wie Hive JSON SerDe können Sie OpenX JSON zur Verarbeitung von JSON-Daten verwenden. Die Daten werden auch als einzeilige Zeichenfolgen aus JSON-codiertem Text dargestellt, die durch eine neue Zeile getrennt sind. Wie der Hive JSON SerDe erlaubt der OpenX JSON SerDe keine doppelten Schlüssel in map- oder struct-Schlüsselnamen.

Überlegungen und Einschränkungen

  • Bei Verwendung des OpenX JSON SerDe können die Anzahl der Ergebnisse und ihre Werte nicht deterministisch sein. Die Ergebnisse können mehr Zeilen als erwartet, weniger Zeilen als erwartet oder unerwartete Nullwerte enthalten, wenn keine in den zugrunde liegenden Daten vorhanden sind. Um dieses Problem zu umgehen, verwenden Sie Hive JSON SerDe, oder schreiben Sie die Daten in einen anderen Dateityp um.

  • Das SerDe erwartet, dass sich jedes JSON-Dokument auf einer einzigen Textzeile befindet, ohne Zeilenabschlusszeichen, die die Felder im Datensatz trennen. Wenn der JSON-Text im hübschen Druckformat vorliegt, erhalten Sie möglicherweise eine Fehlermeldung wie HIVE_CURSOR_ERROR: Zeile ist kein gültiges JSON-Objekt oder HIVE_CURSOR_ERROR: JsonParseException: Unerwartetes Ende der Eingabe: Erwartete Schließmarkierung für OBJEKT, wenn Sie versuchen, die Tabelle abzufragen, nachdem Sie dies erstellt haben.

    Weitere Informationen finden Sie unter JSON-Datendatei in der OpenX-SerDe-Dokumentation auf GitHub.

Optionale Eigenschaften

Im Gegensatz zu Hive JSON SerDe verfügt OpenX JSON SerDe auch über die folgenden optionalen SerDe-Eigenschaften, die für die Behebung von Daten-Inkonsistenzen nützlich sein können.

use.null.for.invalid.data

Optional. Der Standardwert ist FALSE. Wenn auf TRUE gesetzt, verwendet SerDe NULL für Spaltenwerte, deren Deserialisierung in den im Tabellenschema definierten Spaltentyp fehlgeschlagen ist.

Wichtig

Die Einstellung von use.null.for.invalid.data auf TRUE kann zu falschen oder unerwarteten Ergebnissen führen, da NULL-Werte ungültige Daten in Spalten durch Schemakonflikte ersetzen. Wir empfehlen, dass Sie die Daten in Ihren Dateien oder Ihrem Tabellenschema korrigieren, anstatt diese Eigenschaft zu aktivieren. Wenn Sie diese Eigenschaft aktivieren, schlagen Abfragen bei ungültigen Daten nicht fehl, wodurch Sie möglicherweise Probleme mit der Datenqualität nicht entdecken können.

ignore.malformed.json

Optional. Bei Festlegung auf TRUE können Sie eine fehlerhafte JSON-Syntax überspringen. Der Standardwert ist FALSE.

dots.in.keys

Optional. Der Standardwert ist FALSE. Bei Festlegung auf TRUE kann der SerDe die Punkte in Schlüsselnamen durch Unterstriche ersetzen. Wenn der JSON-Datensatz beispielsweise einen Schlüssel mit dem Namen "a.b" enthält, können Sie diese Eigenschaft verwenden, um den Spaltennamen als "a_b" in Athena zu definieren. Standardmäßig (ohne diesen SerDe) lässt Athena keine Punkte in Spaltennamen zu.

case.insensitive

Optional. Der Standardwert ist TRUE. Bei Festlegung auf TRUE wandelt der SerDe alle Großbuchstaben in Kleinbuchstaben um.

Verwenden Sie zur Nutzung von Schlüsselnamen unter Beachtung der Groß-/Kleinschreibung in Ihren Daten WITH SERDEPROPERTIES ("case.insensitive"= FALSE;). Geben Sie dann für jeden Schlüssel, der nicht bereits vollständig aus Kleinbuchstaben besteht, ein Mapping vom Spaltennamen zum Eigenschaftsnamen mit der folgenden Syntax an:

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

Wenn Sie zwei Schlüssel wie URL und Url haben die gleich sind, wenn sie aus Kleinbuchstaben bestehen, kann ein Fehler wie der folgende auftreten:

HIVE_CURSOR_ERROR: Zeile ist kein gültiges JSON-Objekt - JSONException: Doppelter Schlüssel „url"

Um dies zu beheben, setzen Sie die case.insensitive-Eigenschaft auf FALSE und ordnen Sie die Schlüssel verschiedenen Namen zu, wie im folgenden Beispiel gezeigt:

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

Optional. Ordnet Spaltennamen zu JSON-Schlüsseln zu, die nicht mit den Spaltennamen identisch sind. Der mapping-Parameter ist nützlich, wenn die JSON-Daten Schlüssel enthalten, die Schlüsselwörter sind. Wenn Sie beispielsweise einen JSON-Schlüssel mit dem Namen timestamp haben, verwenden Sie die folgende Syntax, um den Schlüssel einer Spalte mit dem Namen ts zuzuordnen:

ROW FORMAT SERDE 'org.openx.data.jsonserde.JsonSerDe' WITH SERDEPROPERTIES ("mapping.ts" = "timestamp")
Zuordnung verschachtelter Feldnamen mit Doppelpunkten zu Hive-kompatiblen Namen

Wenn Sie über einen Feldnamen mit Doppelpunkten innerhalb eines struct verfügen, können Sie die mapping-Eigenschaft verwenden, um das Feld einem Hive-kompatiblen Namen zuzuordnen. Wenn Ihre Spaltentypdefinitionen beispielsweise my:struct:field:string enthalten, können Sie die Definition my_struct_field:string zuordnen, indem Sie den folgenden Eintrag in WITH SERDEPROPERTIES einfügen:

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

Im folgenden Beispiel wird die zugehörige CREATE TABLE-Anweisung gezeigt.

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

Beispiel: Werbedaten

In der folgenden DDL-Anweisung wird der OpenX JSON SerDe verwendet, um eine Tabelle zu erstellen, die auf denselben Beispiel-Online-Werbedaten basiert, die im Beispiel für Hive JSON SerDe verwendet wurden. Ersetzen Sie in der LOCATION-Klausel myregion durch die Kennung der Region, in der Sie Athena ausführen.

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

Beispiel: Deserialisierung von verschachteltem JSON

Sie können die JSON-SerDes verwenden, um komplexere JSON-codierte Daten zu analysieren. Dies erfordert die Verwendung von CREATE TABLE-Anweisungen, die struct- und array- Elemente verwenden, um verschachtelte Strukturen darzustellen.

Im folgenden Beispiel wird eine Athena-Tabelle aus JSON-Daten mit verschachtelten Strukturen erstellt. Das Beispiel hat die folgende Struktur:

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

Beachten Sie, dass OpenX SerDe erwartet, dass jeder JSON-Datensatz in einer einzelnen Textzeile steht. Wenn sie in Amazon S3 gespeichert sind, sollten sich alle Daten im vorherigen Beispiel in einer einzigen Zeile befinden, etwa so:

{"DocId":"AWS","User":{"Id":1234,"Username":"carlos_salazar","Name":"Carlos","ShippingAddress" ...

Die folgende CREATE TABLE-Anweisung verwendet OpenX-JsonSerDe mit den Sammlungsdatentypen struct und array, um Objektgruppen für die Beispieldaten einzurichten.

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

Um die Tabelle abzufragen, verwenden Sie eine SELECT-Anweisung wie die folgende.

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)

Um auf die Datenfelder innerhalb von Strukturen zuzugreifen, verwendet die Beispielabfrage die Punktnotation (z. B. user.name). Um auf Daten innerhalb eines Arrays von Strukturen zuzugreifen (wie beim orders-Feld), können Sie die UNNEST-Funktion verwenden. Die UNNEST-Funktion flacht das Array zu einer temporären Tabelle ab (in diesem Fall mit dem Namen o). Auf diese Weise können Sie die Punktnotation wie bei Strukturen verwenden, um auf die nicht verschachtelten Array-Elemente zuzugreifen (z. B. o.itemid). Der Name temp_table, der im Beispiel zur Veranschaulichung verwendet wird, wird häufig als t abgekürzt.

In der folgenden Tabelle werden die Anfrageergebnisse angezeigt.

# Name Adresse Ort Item_ID Order_date
1 Carlos 123 Main St. Anytown 6789 11/11/2022
2 Carlos 123 Main St. Anytown 4352 12/12/2022