Mit JSON-Daten in GoogleSQL arbeiten
BigQuery unterstützt nativ JSON-Daten mit dem Datentyp JSON
.
In diesem Dokument wird gezeigt, wie Sie eine Tabelle mit einer JSON
-Spalte erstellen, JSON-Daten in eine BigQuery-Tabelle einfügen und JSON-Daten abfragen.
Überblick
JSON ist ein weit verbreitetes Format, das semistrukturierte Daten ermöglicht, da es kein Schema erfordert. Anwendungen können einen „Schema-on-Read“-Ansatz verwenden, bei dem die Anwendung die Daten aufnimmt und dann basierend auf Annahmen über das Schema dieser Daten Abfragen durchführt. Dieser Ansatz unterscheidet sich vom Typ STRUCT
in BigQuery, der ein festes Schema erfordert, das für alle Werte erzwungen wird, die in einer Spalte vom Typ STRUCT
gespeichert sind.
Mit dem Datentyp JSON
können Sie semistrukturierte JSON-Daten in BigQuery laden, ohne im Voraus ein Schema für die JSON-Daten bereitzustellen.
Dadurch können Sie Daten speichern und abfragen, die nicht immer den festgelegten Schemas und Datentypen entsprechen. Durch die Aufnahme von JSON-Daten als JSON
-Datentyp kann BigQuery jedes JSON-Feld einzeln codieren und verarbeiten. Sie können dann die Werte der Felder und Arrayelemente innerhalb der JSON-Daten mit dem Operator für den Feldzugriff abfragen, was JSON-Abfragen intuitiv und kostengünstig macht.
Beschränkungen
- Wenn Sie einen Batch-Ladejob verwenden, um JSON-Daten in eine Tabelle aufzunehmen, müssen die Quelldaten im CSV-, Avro- oder JSON-Format vorliegen. Andere Batch-Ladeformate werden nicht unterstützt.
- Der Datentyp
JSON
hat ein Verschachtelungslimit von 500. - Sie können keine Legacy-SQL verwenden, um eine Tabelle mit
JSON
-Typen abzufragen. - Zugriffsrichtlinien auf Zeilenebene können nicht auf
JSON
-Spalten angewendet werden.
Weitere Informationen zu den Attributen des JSON
-Datentyps finden Sie unter JSON
-Typ.
Tabelle mit einer JSON
-Spalte erstellen
Sie können eine leere Tabelle mit einer JSON
-Spalte mithilfe von SQL oder des bq-Befehlszeilentools erstellen.
SQL
Verwenden Sie die Anweisung CREATE TABLE
und deklarieren Sie eine Spalte mit dem Typ JSON
.
Öffnen Sie in der Google Cloud Console die Seite BigQuery.
Geben Sie im Abfrageeditor die folgende Anweisung ein:
CREATE TABLE mydataset.table1( id INT64, cart JSON );
Klicken Sie auf
Ausführen.
Informationen zum Ausführen von Abfragen finden Sie unter Interaktive Abfrage ausführen.
bq
Verwenden Sie den Befehl bq mk
und geben Sie ein Tabellenschema mit dem Datentyp JSON
an.
bq mk --table mydataset.table1 id:INT64,cart:JSON
Sie können keine Tabelle in JSON
-Spalten partitionieren oder gruppieren, da die Gleichheits- und Vergleichsoperatoren nicht für den Typ JSON
definiert sind.
JSON
-Werte erstellen
JSON
-Werte können so erstellt werden:
- Verwenden Sie SQL, um ein
JSON
-Literal zu erstellen. - Verwenden Sie die Funktion
PARSE_JSON
, um einenSTRING
-Wert in einenJSON
-Wert zu konvertieren. - Mit der Funktion
TO_JSON
können Sie einen SQL-Wert in einenJSON
-Wert konvertieren. - Mit der Funktion
JSON_ARRAY
können Sie ein JSON-Array aus SQL-Werten erstellen. - Mit der Funktion
JSON_OBJECT
können Sie ein JSON-Objekt aus Schlüssel/Wert-Paaren erstellen.
Einen JSON
-Wert erstellen
Im folgenden Beispiel werden JSON
-Werte in eine Tabelle eingefügt:
INSERT INTO mydataset.table1 VALUES (1, JSON '{"name": "Alice", "age": 30}'), (2, JSON_ARRAY(10, ['foo', 'bar'], [20, 30])), (3, JSON_OBJECT('foo', 10, 'bar', ['a', 'b']));
STRING
-Typ in JSON
-Typ konvertieren
Im folgenden Beispiel wird ein JSON-formatierter STRING
-Wert mithilfe der Funktion PARSE_JSON
konvertiert. In diesem Beispiel wird eine Spalte aus einer vorhandenen Tabelle in einen JSON
-Typ konvertiert und die Ergebnisse in einer neuen Tabelle gespeichert.
CREATE OR REPLACE TABLE mydataset.table_new
AS (
SELECT
id, SAFE.PARSE_JSON(cart) AS cart_json
FROM
mydataset.old_table
);
Das in diesem Beispiel verwendete Präfix SAFE
sorgt dafür, dass alle Konvertierungsfehler als NULL
-Werte zurückgegeben werden.
Schematisierte Daten in JSON konvertieren
Im folgenden Beispiel werden Schlüssel/Wert-Paare mit der Funktion JSON_OBJECT
in das JSON-Format konvertiert.
WITH Fruits AS ( SELECT 0 AS id, 'color' AS k, 'Red' AS v UNION ALL SELECT 0, 'fruit', 'apple' UNION ALL SELECT 1, 'fruit','banana' UNION ALL SELECT 1, 'ripe', 'true' ) SELECT JSON_OBJECT(ARRAY_AGG(k), ARRAY_AGG(v)) AS json_data FROM Fruits GROUP BY id
Das Ergebnis lautet:
+----------------------------------+ | json_data | +----------------------------------+ | {"color":"Red","fruit":"apple"} | | {"fruit":"banana","ripe":"true"} | +----------------------------------+
SQL-Typ in JSON
-Typ konvertieren
Im folgenden Beispiel wird ein SQL-STRUCT
-Wert mithilfe der Funktion TO_JSON
in einen JSON
-Wert konvertiert:
SELECT TO_JSON(STRUCT(1 AS id, [10,20] AS coordinates)) AS pt;
Das Ergebnis lautet:
+--------------------------------+ | pt | +--------------------------------+ | {"coordinates":[10,20],"id":1} | +--------------------------------+
JSON-Daten aufnehmen
Sie können JSON-Daten auf folgende Weise in eine BigQuery-Tabelle aufnehmen:
- Verwenden Sie einen Batch-Ladejob, um
JSON
-Spalten aus den folgenden Formaten zu laden: - Verwenden Sie die BigQuery Storage Write API.
- Verwenden Sie die Legacy-Streaming-API
tabledata.insertAll
.
Aus CSV-Dateien laden
Im folgenden Beispiel wird davon ausgegangen, dass Sie eine CSV-Datei namens file1.csv
haben, die die folgenden Einträge enthält:
1,20 2,"""This is a string""" 3,"{""id"": 10, ""name"": ""Alice""}"
Beachten Sie, dass die zweite Spalte JSON-Daten enthält, die als String codiert sind. Dies umfasst das korrekte Maskieren von Anführungszeichen für das CSV-Format. Im CSV-Format werden Anführungszeichen mithilfe der Zwei-Zeichen-Sequenz ""
maskiert.
Wenn Sie diese Datei mit dem bq-Befehlszeilentool laden möchten, verwenden Sie den Befehl bq load
:
bq load --source_format=CSV mydataset.table1 file1.csv id:INTEGER,json_data:JSON
bq show mydataset.table1
Last modified Schema Total Rows Total Bytes
----------------- -------------------- ------------ -------------
22 Dec 22:10:32 |- id: integer 3 63
|- json_data: json
Aus durch Zeilenumbruch getrennten JSON-Dateien laden
Im folgenden Beispiel wird davon ausgegangen, dass Sie eine Datei namens file1.jsonl
haben, die die folgenden Einträge enthält:
{"id": 1, "json_data": 20} {"id": 2, "json_data": "This is a string"} {"id": 3, "json_data": {"id": 10, "name": "Alice"}}
Wenn Sie diese Datei mit dem bq-Befehlszeilentool laden möchten, verwenden Sie den Befehl bq load
:
bq load --source_format=NEWLINE_DELIMITED_JSON mydataset.table1 file1.jsonl id:INTEGER,json_data:JSON
bq show mydataset.table1
Last modified Schema Total Rows Total Bytes
----------------- -------------------- ------------ -------------
22 Dec 22:10:32 |- id: integer 3 63
|- json_data: json
Storage Write API verwenden
Sie können die Storage Write API verwenden, um JSON-Daten aufzunehmen. Im folgenden Beispiel wird der Python-Client der Storage Write API verwendet.
Definieren Sie einen Protokollpuffer für die serialisierten Streamingdaten. Die JSON-Daten werden als String codiert. Im folgenden Beispiel enthält das Feld json_col
JSON-Daten.
message SampleData { optional string string_col = 1; optional int64 int64_col = 2; optional string json_col = 3; }
Formatieren Sie die JSON-Daten für jede Zeile als STRING
-Wert:
row.json_col = '{"a": 10, "b": "bar"}' row.json_col = '"This is a string"' # The double-quoted string is the JSON value. row.json_col = '10'
Hängen Sie die Zeilen an den Schreibstream an, wie im Codebeispiel gezeigt. Die Clientbibliothek verarbeitet die Serialisierung in das Protokollpufferformat.
Legacy-Streaming-API verwenden
Im folgenden Beispiel werden JSON-Daten aus einer lokalen Datei geladen und mithilfe der Legacy-Streaming API an BigQuery gestreamt.
from google.cloud import bigquery
import json
# TODO(developer): Replace these variables before running the sample.
project_id = 'MY_PROJECT_ID'
table_id = 'MY_TABLE_ID'
client = bigquery.Client(project=project_id)
table_obj = client.get_table(table_id)
# The column json_data is represented as a string.
rows_to_insert = [
{"id": 1, "json_data": json.dumps(20)},
{"id": 2, "json_data": json.dumps("This is a string")},
{"id": 3, "json_data": json.dumps({"id": 10, "name": "Alice"})}
]
# Throw errors if encountered.
# https://cloud.google.com/python/docs/reference/bigquery/latest/google.cloud.bigquery.client.Client#google_cloud_bigquery_client_Client_insert_rows
errors = client.insert_rows(table=table_obj, rows=rows_to_insert)
if errors == []:
print("New rows have been added.")
else:
print("Encountered errors while inserting rows: {}".format(errors))
Weitere Informationen finden Sie unter Daten in BigQuery streamen.
JSON-Daten abfragen
In diesem Abschnitt wird beschrieben, wie Sie mithilfe von GoogleSQL Werte aus dem JSON-Format extrahieren. Bei JSON wird zwischen Groß- und Kleinschreibung unterschieden und sie unterstützt UTF-8 sowohl in Feldern als auch in Werten.
In den Beispielen in diesem Abschnitt wird die folgende Tabelle verwendet:
CREATE OR REPLACE TABLE mydataset.table1(id INT64, cart JSON); INSERT INTO mydataset.table1 VALUES (1, JSON """{ "name": "Alice", "items": [ {"product": "book", "price": 10}, {"product": "food", "price": 5} ] }"""), (2, JSON """{ "name": "Bob", "items": [ {"product": "pen", "price": 20} ] }""");
Werte als JSON extrahieren
Bei einem JSON
-Typ in BigQuery können Sie mit dem Operator für den Feldzugriff auf die Felder in einem JSON-Ausdruck zugreifen.
Im folgenden Beispiel wird das Feld name
der Spalte cart
zurückgegeben.
SELECT cart.name FROM mydataset.table1;
+---------+ | name | +---------+ | "Alice" | | "Bob" | +---------+
Verwenden Sie den JSON-Skriptoperator, um auf ein Arrayelement zuzugreifen.
Im folgenden Beispiel wird das erste Element des Arrays items
zurückgegeben:
SELECT cart.items[0] AS first_item FROM mydataset.table1
+-------------------------------+ | first_item | +-------------------------------+ | {"price":10,"product":"book"} | | {"price":20,"product":"pen"} | +-------------------------------+
Sie können auch den JSON-Skriptoperator verwenden, um auf die Mitglieder eines JSON-Objekts anhand des Namens zu verweisen:
SELECT cart['name'] FROM mydataset.table1;
+---------+ | name | +---------+ | "Alice" | | "Bob" | +---------+
Für Skriptvorgänge kann der Ausdruck in den Klammern ein beliebiger String- oder Ganzzahlausdruck sein, einschließlich nicht konstanter Ausdrücke:
DECLARE int_val INT64 DEFAULT 0; SELECT cart[CONCAT('it','ems')][int_val + 1].product AS item FROM mydataset.table1;
+--------+ | item | +--------+ | "food" | | NULL | +--------+
Operatoren für Feldzugriff und Startskripts geben beide JSON
-Typen zurück, sodass Sie Ausdrücke verketten können, die sie verwenden, oder das Ergebnis an andere Funktionen übergeben, die JSON
-Typen verwenden.
Diese Operatoren sind syntaktischer Sugar für die Funktion JSON_QUERY
. Der Ausdruck cart.name
entspricht beispielsweise JSON_QUERY(cart, "$.name")
.
Wenn ein Mitglied mit dem angegebenen Namen nicht im JSON-Objekt gefunden wird oder das JSON-Array kein Element mit der angegebenen Position enthält, geben diese Operatoren SQL NULL
zurück.
SELECT cart.address AS address, cart.items[1].price AS item1_price FROM mydataset.table1;
+---------+-------------+ | address | item1_price | +---------+-------------+ | NULL | NULL | | NULL | 5 | +---------+-------------+
Die Gleichheits- und Vergleichsoperatoren werden nicht zum Datentyp JSON
definiert.
Daher können Sie JSON
-Werte nicht direkt in Klauseln wie GROUP BY
oder ORDER BY
verwenden. Verwenden Sie stattdessen die Funktion JSON_VALUE
, um Feldwerte als SQL-Strings zu extrahieren, wie im nächsten Abschnitt beschrieben.
Werte als Strings extrahieren
Die Funktion JSON_VALUE
extrahiert einen skalaren Wert und gibt ihn als SQL-String zurück. Gibt SQL NULL
zurück, wenn cart.name
nicht auf einen skalaren Wert in der JSON-Datei verweist.
SELECT JSON_VALUE(cart.name) AS name FROM mydataset.table1;
+-------+ | name | +-------+ | Alice | +-------+
Sie können die JSON_VALUE
-Funktion in Kontexten verwenden, die Übereinstimmungen oder Vergleiche erfordern, z. B. WHERE
-Klauseln und GROUP BY
-Klauseln. Das folgende Beispiel zeigt eine WHERE
-Klausel, die nach einem JSON
-Wert filtert:
SELECT cart.items[0] AS first_item FROM mydataset.table1 WHERE JSON_VALUE(cart.name) = 'Alice';
+-------------------------------+ | first_item | +-------------------------------+ | {"price":10,"product":"book"} | +-------------------------------+
Alternativ können Sie die Funktion STRING
verwenden, die einen JSON-String extrahiert und diesen Wert als SQL-STRING
zurückgibt.
Beispiel:
SELECT STRING(JSON '"purple"') AS color;
+--------+ | color | +--------+ | purple | +--------+
Neben STRING
müssen Sie möglicherweise JSON
-Werte extrahieren und als weiteren SQL-Datentyp zurückgeben. Die folgenden Funktionen zur Wertextraktion sind verfügbar:
Zum Abrufen des Typs des JSON
-Werts können Sie die Funktion JSON_TYPE
verwenden.
JSON flexibel konvertieren
Mit LAX Conversion
-Funktionen können Sie einen JSON
-Wert flexibel und fehlerfrei in einen skalaren SQL-Wert konvertieren.
Das folgende Beispiel zeigt die Leistungsfähigkeit dieser Funktionen. LAX_IN64
leitet die Eingabe automatisch ab und verarbeitet sie korrekt.
SELECT LAX_INT64(JSON '"10"') AS id;
+----+ | id | +----+ | 10 | +----+
Zusätzlich zu LAX_IN64
können Sie mit den folgenden Funktionen flexibel in andere SQL-Typen in JSON konvertieren:
Arrays aus JSON extrahieren
JSON kann JSON-Arrays enthalten, die nicht direkt einem ARRAY<JSON>
-Typ in BigQuery entsprechen. Mit den folgenden Funktionen können Sie eine ARRAY
von BigQuery aus JSON extrahieren:
JSON_QUERY_ARRAY
: Extrahiert ein Array und gibt es alsARRAY<JSON>
von JSON zurück.JSON_VALUE_ARRAY
: Extrahiert ein Array von skalaren Werten und gibt es alsARRAY<STRING>
skalarer Werte zurück.
Im folgenden Beispiel werden JSON-Arrays mit JSON_QUERY_ARRAY
extrahiert.
SELECT JSON_QUERY_ARRAY(cart.items) AS items FROM mydataset.table1;
+----------------------------------------------------------------+ | items | +----------------------------------------------------------------+ | [{"price":10,"product":"book"}","{"price":5,"product":"food"}] | | [{"price":20,"product":"pen"}] | +----------------------------------------------------------------+
Verwenden Sie den Operator UNNEST
, um ein Array in einzelne Elemente zu unterteilen. Dieser gibt eine Tabelle mit einer Zeile für jedes Element im Array zurück. Im folgenden Beispiel wird das Mitglied product
von jedem Mitglied des Arrays items
ausgewählt:
SELECT id, JSON_VALUE(item.product) AS product FROM mydataset.table1, UNNEST(JSON_QUERY_ARRAY(cart.items)) AS item ORDER BY id;
+----+---------+ | id | product | +----+---------+ | 1 | book | | 1 | food | | 2 | pen | +----+---------+
Das nächste Beispiel ist ähnlich, nutzt jedoch die Funktion ARRAY_AGG
, um die Werte wieder in einem SQL-Array zusammenzufassen.
SELECT id, ARRAY_AGG(JSON_VALUE(item.product)) AS products FROM mydataset.table1, UNNEST(JSON_QUERY_ARRAY(cart.items)) AS item GROUP BY id ORDER BY id;
+----+-----------------+ | id | products | +----+-----------------+ | 1 | ["book","food"] | | 2 | ["pen"] | +----+-----------------+
Weitere Informationen zu Arrays finden Sie unter Mit Arrays in GoogleSQL arbeiten.
JSON-Nullen
Der Typ JSON
hat einen speziellen Wert für null
, der sich vom SQL-NULL
unterscheidet. Ein JSON-null
wird nicht als SQL-NULL
-Wert behandelt, wie im folgenden Beispiel gezeigt.
SELECT JSON 'null' IS NULL;
+-------+ | f0_ | +-------+ | false | +-------+
Wenn Sie ein JSON-Feld mit einem null
-Wert extrahieren, hängt das Verhalten von der Funktion ab:
- Die Funktion
JSON_QUERY
gibt einen JSON-null
zurück, da es sich um einen gültigenJSON
-Wert handelt. - Die Funktion
JSON_VALUE
gibt den SQL-NULL
zurück, da JSONnull
kein skalarer Wert ist.
Das folgende Beispiel zeigt die verschiedenen Verhaltensweisen:
SELECT json.a AS json_query, -- Equivalent to JSON_QUERY(json, '$.a') JSON_VALUE(json, '$.a') AS json_value FROM (SELECT JSON '{"a": null}' AS json);
+------------+------------+ | json_query | json_value | +------------+------------+ | null | NULL | +------------+------------+