CodeGym /Kurse /SQL SELF /JSON-Objekte zusammenführen und modifizieren mit dem Oper...

JSON-Objekte zusammenführen und modifizieren mit dem Operator || und der Funktion jsonb_concat()

SQL SELF
Level 34 , Lektion 0
Verfügbar

Wenn JSONB so eine Art Zauberkiste ist, in die wir Daten packen, dann sind || und jsonb_concat() die Tools, mit denen wir diese Kisten zusammenfügen oder ihren Inhalt verändern können. Im echten Leben brauchst du manchmal mehrere JSON-Objekte zusammenzuführen, Daten von einem ins andere zu schieben oder Arrays zu einer einzigen Liste zu verbinden.

Stell dir zum Beispiel vor, du hast zwei JSONB-Objekte:

{"name": "Alice", "age": 25}

und

{"city": "Wonderland", "hobbies": ["lesen", "schach"]}

Du willst folgendes Ergebnis bekommen:

{"name": "Alice", "age": 25, "city": "Wonderland", "hobbies": ["lesen", "schach"]}

Oder zwei JSONB-Arrays zusammenführen:

[1, 2, 3]

und

[4, 5, 6]

damit das Ergebnis so aussieht:

[1, 2, 3, 4, 5, 6]

Das alles geht easy mit || oder jsonb_concat(). Lass uns anschauen, wie das läuft.

Operator || zum Zusammenführen von JSONB

Mit dem Operator || kannst du zwei JSONB-Objekte oder Arrays in PostgreSQL zusammenführen. Das ist einfach, schnell und unkompliziert. Hier die wichtigsten Regeln:

  • Wenn du zwei JSONB-Objekte zusammenfügst, enthält das Ergebnis die Keys und Werte von beiden Objekten.
  • Wenn Keys gleich sind, überschreibt der Wert vom rechten Operand den vom linken.
  • Wenn du JSONB-Arrays zusammenfügst, werden die Elemente beider Arrays zu einem Array kombiniert.

Beispiel 1: Zwei JSONB-Objekte zusammenführen

SELECT '{"name": "Alice", "age": 25}'::jsonb || '{"city": "Wonderland", "hobbies": ["lesen", "schach"]}'::jsonb AS merged_object;

Ergebnis:

{"name": "Alice", "age": 25, "city": "Wonderland", "hobbies": ["lesen", "schach"]}

Beispiel 2: Werte aktualisieren bei gleichen Keys

SELECT '{"name": "Alice", "age": 25}'::jsonb || '{"age": 30, "city": "Wonderland"}'::jsonb AS updated_object;

Ergebnis:

{"name": "Alice", "age": 30, "city": "Wonderland"}

Beachte, dass der Wert vom Key "age" aus dem rechten Objekt den Wert vom linken ersetzt hat.

Beispiel 3: Arrays zusammenführen

SELECT '[1, 2, 3]'::jsonb || '[4, 5, 6]'::jsonb AS merged_array;

Ergebnis:

[1, 2, 3, 4, 5, 6]

Funktion jsonb_concat() zum Zusammenführen von JSONB

Die Funktion jsonb_concat() funktioniert ähnlich wie der Operator ||, ist aber flexibler, wenn du sie in Funktionen, Triggern oder dynamischen Abfragen brauchst. Sie nimmt zwei Argumente vom Typ JSONB und gibt das zusammengeführte Ergebnis zurück.

Beispiel: jsonb_concat() verwenden

SELECT jsonb_concat('{"a": 1, "b": 2}'::jsonb, '{"b": 3, "c": 4}'::jsonb) AS combined;

Ergebnis:

{"a": 1, "b": 3, "c": 4}

Objekte und Arrays zusammenführen: Besonderheiten und Details

Wenn du Objekte mit gleichen Keys zusammenführst, solltest du wissen, dass die Werte aus dem rechten Objekt Vorrang haben.

Zum Beispiel:

SELECT '{"key1": "wert1"}'::jsonb || '{"key1": "wert2"}'::jsonb AS result;

Ergebnis:

{"key1": "wert2"}

Wenn du vermeiden willst, dass Werte überschrieben werden, solltest du solche Daten in unterschiedlichen Keys speichern oder einen anderen Ansatz wählen (zum Beispiel ein Array).

Und Arrays werden immer durch Anhängen der Elemente vom rechten Array ans linke zusammengeführt. Zum Beispiel:

SELECT '["a", "b"]'::jsonb || '["c", "d"]'::jsonb AS result;

Ergebnis:

["a", "b", "c", "d"]

Wenn im Array Objekte drin sind, bleibt die Reihenfolge erhalten:

SELECT '[{"id": 1}, {"id": 2}]'::jsonb || '[{"id": 3}]'::jsonb AS result;

Ergebnis:

[{"id": 1}, {"id": 2}, {"id": 3}]

Praktische Beispiele

User-Profil aktualisieren. Angenommen, wir haben eine Tabelle users, in der Profile als JSONB gespeichert werden:

CREATE TABLE users (
    id SERIAL PRIMARY KEY,
    profile JSONB
);

INSERT INTO users (profile) VALUES ('{"name": "Alice", "age": 25}');

Jetzt wollen wir die Stadt hinzufügen, in der sie wohnt:

UPDATE users 
SET profile = profile || '{"city": "Wonderland"}'
WHERE id = 1;

Ergebnis der Abfrage:

{"name": "Alice", "age": 25, "city": "Wonderland"}

Bestelldaten zusammenführen. Nehmen wir an, wir haben eine Tabelle orders:

CREATE TABLE orders (
    id SERIAL PRIMARY KEY,
    details JSONB
);

INSERT INTO orders (details) VALUES ('{"items": [{"produkt": "laptop", "anzahl": 1}]}');

Jetzt fügen wir noch ein Produkt zur Bestellung hinzu:

UPDATE orders
SET details = jsonb_set(
    details,
    '{items}',
    details->'items' || '[{"produkt": "maus", "anzahl": 2}]'::jsonb
)
WHERE id = 1;

Ergebnis der Abfrage:

{"items": [{"produkt": "laptop", "anzahl": 1}, {"produkt": "maus", "anzahl": 2}]}

Unterschiede zwischen || und jsonb_concat()

Funktional sind der Operator || und die Funktion jsonb_concat() identisch. Benutze || für einfache Abfragen, weil es kürzer ist. Die Funktion jsonb_concat() ist praktisch, wenn du sie explizit in Programmen oder Triggern aufrufen willst.

Typische Fehler und wie du sie vermeidest

Fehler: Versuch, inkompatible Typen zusammenzuführen.

SELECT '{"key": "wert"}'::jsonb || '["wert"]'::jsonb;

Ergebnis:

ERROR:  cannot concatenate jsonb objects and arrays

Links steht ein Objekt, rechts ein Array – PostgreSQL kann die nicht einfach so zusammenführen. Damit das klappt, müssen beide Operanden vom gleichen Typ sein: entweder zwei Objekte oder zwei Arrays.

Vergessen: Keine Indizes bei Arbeit mit JSONB

Wenn du oft nach Werten in JSONB-Feldern filterst, aber keine Indizes hast, werden die Abfragen richtig langsam. Das ist kein Fehler im klassischen Sinn, aber die Performance leidet extrem. Vergiss nicht, GIN-Indizes zu nutzen:

CREATE INDEX idx_profile_data ON employees USING gin(profile);
Kommentare
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION