Opdater :for 9.5+ er der eksplicitte operatorer, du kan bruge med jsonb
(hvis du har en json
indtastet kolonne, kan du bruge casts til at anvende en ændring):
Sletning af en nøgle (eller et indeks) fra et JSON-objekt (eller fra et array) kan gøres med -
operatør:
SELECT jsonb '{"a":1,"b":2}' - 'a', -- will yield jsonb '{"b":2}'
jsonb '["a",1,"b",2]' - 1 -- will yield jsonb '["a","b",2]'
Sletning fra dybt i et JSON-hierarki kan gøres med #-
operatør:
SELECT '{"a":[null,{"b":[3.14]}]}' #- '{a,1,b,0}'
-- will yield jsonb '{"a":[null,{"b":[]}]}'
For 9.4 kan du bruge en ændret version af det originale svar (nedenfor), men i stedet for at aggregere en JSON-streng, kan du samle til en json
objekt direkte med json_object_agg()
.
Relateret:andre JSON-manipulationer inden for PostgreSQL:
- Hvordan ændrer jeg felter i den nye PostgreSQL JSON-datatype?
Oprindeligt svar (gælder for PostgreSQL 9.3):
Hvis du har mindst PostgreSQL 9.3, kan du opdele dit objekt i par med json_each()
og filtrer dine uønskede felter, og byg derefter json op igen manuelt. Noget som:
SELECT data::text::json AS before,
('{' || array_to_string(array_agg(to_json(l.key) || ':' || l.value), ',') || '}')::json AS after
FROM (VALUES ('{"attrA":1,"attrB":true,"attrC":["a","b","c"]}'::json)) AS v(data),
LATERAL (SELECT * FROM json_each(data) WHERE "key" <> 'attrB') AS l
GROUP BY data::text
Med 9.2 (eller lavere) er det ikke muligt.
Rediger :
En mere bekvem form er at oprette en funktion, som kan fjerne et vilkårligt antal attributter i en json
felt:
Rediger 2 :string_agg()
er billigere end array_to_string(array_agg())
CREATE OR REPLACE FUNCTION "json_object_delete_keys"("json" json, VARIADIC "keys_to_delete" TEXT[])
RETURNS json
LANGUAGE sql
IMMUTABLE
STRICT
AS $function$
SELECT COALESCE(
(SELECT ('{' || string_agg(to_json("key") || ':' || "value", ',') || '}')
FROM json_each("json")
WHERE "key" <> ALL ("keys_to_delete")),
'{}'
)::json
$function$;
Med denne funktion er alt hvad du skal gøre at køre forespørgslen nedenfor:
UPDATE my_table
SET data = json_object_delete_keys(data, 'attrB');