PostgreSQL offre supporto nativo per i dati JSON tramite json (memorizza il testo così com'è) e jsonb (formato binario scomposto con supporto a indici GIN e ricerche rapide).
Operatori di estrazione
La freccia singola (->, #>) restituisce json/jsonb. La freccia doppia (->>, #>>) restituisce text.
SELECT * FROM users WHERE data->>'name' = 'John';
SELECT data->>'name' AS name FROM users;
| Operatore | Tipo sinistro | Tipo destro | Descrizione | Tipo restituito |
|---|---|---|---|---|
-> |
jsonb |
int |
Ottieni elemento dell'array tramite indice a base 0 | jsonb |
-> |
jsonb |
text |
Ottieni campo dell'oggetto tramite chiave | jsonb |
#> |
jsonb |
text[] |
Ottieni valore al percorso specificato | jsonb |
->> |
jsonb |
int |
Ottieni elemento dell'array come testo | text |
->> |
jsonb |
text |
Ottieni campo dell'oggetto come testo | text |
#>> |
jsonb |
text[] |
Ottieni valore al percorso come testo | text |
Esempi di query sui percorsi
-- Extract nested data.address.city as text
SELECT data#>>'{address,city}' FROM customers;
-- Extract second element in items array
SELECT order_info->'items'->>1 FROM orders;
Operatori booleani e di contenimento (solo jsonb)
-- Check if JSON object contains a specific top-level key
SELECT * FROM users WHERE data ? 'email';
-- Check if JSON contains all keys in array
SELECT * FROM users WHERE data ?& array['name', 'email'];
-- Check if JSON contains any key in array
SELECT * FROM users WHERE data ?| array['mobile', 'email'];
-- Containment: Left contains Right
SELECT * FROM users WHERE data @> '{"role": "admin"}'::jsonb;
-- Contained by: Left is contained within Right
SELECT * FROM users WHERE data <@ '{"role": "admin", "active": true}'::jsonb;
Modifica e aggiornamento dei dati JSONB
Concatenazione ed eliminazione di chiavi
-- Append or update key in jsonb object
UPDATE users SET data = data || '{"active": true}'::jsonb WHERE id = 1;
-- Delete key from object
UPDATE users SET data = data - 'temporary_token' WHERE id = 1;
-- Delete element from array by index
UPDATE users SET tags = tags - 1 WHERE id = 1;
-- Delete nested path
UPDATE users SET data = data #- '{profile,avatar}' WHERE id = 1;
Funzione jsonb_set
-- Syntax: jsonb_set(target, path, new_value, create_missing)
UPDATE users
SET data = jsonb_set(data, '{contact,phone}', '"555-0199"', true)
WHERE id = 1;
Funzioni di aggregazione e costruzione
-- Convert rows to JSON array
SELECT json_agg(u) FROM (SELECT id, name FROM users) u;
-- Build JSON object from key-value pairs
SELECT json_build_object('id', id, 'username', name) FROM users;
-- Expand JSON object to table rows
SELECT * FROM json_each('{"a": 1, "b": 2}');
-- Returns columns: key (text), value (json)