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 здесь.]

Другие вопросы по тегам