Postgres JSON эквивалентен оператору вычитания HSTORE
Расширение Postgres' hstore
имеет аккуратный оператор вычитания:
hstore - text[]
hstore - hstore
В первом случае он удаляет пары ключ / значение, где ключи находятся в массиве строк; во втором случае он удаляет все соответствующие пары ключ / значение из первого hstore, которые появляются во втором hstore.
Похоже, что этот оператор не существует для нового типа данных jsonb
. Есть ли простой способ выполнить эти задачи?
2 ответа:
Ключ-это
json_each()
функция и возможность в PostgreSQL вручную создавать значение json.Вот функция, которая может обрабатывать
json - text[]
: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$;
Чтобы обработать случай
json - json
, Вам просто нужно изменить предложениеWHERE
:WHERE "json"->>"key" <> ("remove"->>"key")),
Принятый ответ велик, но был бы улучшен для случая
json - json
, проверив также null:WHERE NOT null_as_value_cmp((this_j->>"key"), (that_j->>"key"))
Без проверки
NULL
Вы получаете{}
вместо{"a":1}
:# select json_subtract('{"a":1, "b":2}'::json, '{"b":2}'::json); json_subtract --------------- {} (1 row)
null_as_value_cmp
является чем-то вроде этого и получает вокругJsNull
будучи представленным как база данныхNULL
CREATE OR REPLACE FUNCTION null_as_value_cmp( a text, b text ) RETURNS boolean LANGUAGE sql IMMUTABLE CALLED ON NULL INPUT AS $function$ SELECT CASE WHEN a IS NULL AND b IS NULL THEN TRUE WHEN (a IS NULL AND b IS NOT NULL) THEN FALSE WHEN (a IS NOT NULL AND b IS NULL) THEN FALSE WHEN a = b THEN TRUE ELSE FALSE END; $function$;
[у меня недостаточно репутации, чтобы комментировать; не уверен в протоколе SO здесь.]