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будучи представленным как база данныхNULLCREATE 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 здесь.]