Ce face jsonb_build_object, jsonb_agg și jsonb_set
Pe lângă interogarea documentelor JSONB, PostgreSQL oferă funcții puternice pentru generarea de răspunsuri JSON direct din baza de date (jsonb_build_object, to_jsonb, jsonb_agg) și pentru modificarea parțială a câmpurilor dintr-o coloană JSONB fără a rescrie tot documentul din aplicație (jsonb_set și operatorul de concatenare || sau ștergere -).
Combinând jsonb_build_object() cu funcția de agregare jsonb_agg(), poți transforma o relație părinte-copil (ex: o comandă cu toate liniile ei de produse) într-un singur obiect JSON ierarhic gata de trimis către un API REST.
Clauze, operatori și argumente
| Clauză / Operator | Descriere |
|---|---|
jsonb_build_object(k1, v1, k2, v2, ...) |
Construiește un obiect JSONB din perechi alternante de cheie și valoare. |
jsonb_agg(expresie [ORDER BY ...]) |
Funcție de agregare care adună valorile dintr-un grup într-un array JSONB. |
jsonb_set(tinta, cale, val_jsonb [, create]) |
Înlocuiește sau adaugă (dacă create = true, implicit) valoarea de la cale (ex: '{adresa,oras}'). |
jsonb1 || jsonb2 |
Concatenează două obiecte JSONB la nivelul rădăcină (cheile din dreapta suprascriu cheile din stânga). |
jsonb - 'cheie' / #- '{cale,cheie}' |
Șterge o cheie de la nivelul rădăcină (-) sau de la o cale imbricată (#-). |
jsonb_array_elements(array_jsonb) |
Despachetează un array JSONB într-un set de rânduri (câte un rând pentru fiecare element). |
Exemple
Exemplul 1: Generarea unui obiect JSON ierarhic (comandă + linii) cu jsonb_build_object și jsonb_agg
Agregăm liniile fiecărei comenzi într-un array JSONB ordonat, gata de serializare în API.
SELECT c.id AS comanda_id,
jsonb_build_object(
'comanda_id', c.id,
'client', cl.nume,
'total_lei', c.total_lei,
'articole', COALESCE(
jsonb_agg(
jsonb_build_object(
'sku', lc.sku,
'cantitate', lc.cantitate,
'pret', lc.pret_unitar
) ORDER BY lc.id
) FILTER (WHERE lc.id IS NOT NULL),
'[]'::jsonb
)
) AS payload_json
FROM comenzi c
JOIN clienti cl ON cl.id = c.client_id
LEFT JOIN linii_comanda lc ON lc.comanda_id = c.id
WHERE c.id = 5042
GROUP BY c.id, cl.nume;
Rezultat interogare
comanda_id | payload_json
------------+-------------------------------------------------------------------------------------------------------------------
5042 | {"client": "Ana Marinescu", "articole": [{"sku": "SSD-1TB", "pret": 420.50, "cantitate": 1}], "total_lei": 420.50, "comanda_id": 5042}
(1 row)
Exemplul 2: Actualizarea unei chei imbricate cu jsonb_set și ștergerea unei chei vechi cu –
Actualizăm rezoluția din sub-obiectul ecran și ștergem simultan cheia învechită cod_intern.
UPDATE produse
SET specificatii = jsonb_set(
specificatii - 'cod_intern',
'{ecran,rezolutie}',
'"3840x2160"'::jsonb,
true
)
WHERE id = 41
RETURNING id, specificatii;
Rezultat interogare
id | specificatii
----+-------------------------------------------------------------
41 | {"ecran": {"diagonala": 27, "rezolutie": "3840x2160"}, "rata_hz": 144}
(1 row)
UPDATE 1
Greșeli frecvente
- La
jsonb_set(tinta, '{a,b}', val), dacă obiectul părinteanu există deloc întinta, funcția nu va crea automatași va lăsa documentul neschimbat. - Dacă oricare element din
jsonb_setesteNULLSQL (nu'null'::jsonb), întreaga funcție returneazăNULL(deoarece este definită caSTRICT) și poate șterge accidental toată coloana dacă nu foloseștito_jsonb()sauCOALESCE.
Comenzi și funcții înrudite
JSONB și operatorii ->, ->>, @>, ?: Interoghează și filtrează documente binare JSONB folosind operatorii de extracție (->, ->>) și incluziune (@>, ?).GROUP BY, HAVING și clauza FILTER: Grupează rândurile pentru agregări și aplică condiții individuale pe fiecare funcție agregată prin FILTER (WHERE …).ARRAY, ANY() și unnest(): Stochează și manipulează tablouri tipizate (text[], int[]), verifică apartenența cu ANY() și le extinde în rânduri cu unnest().