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
case, также проверяя на 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 здесь.]