Postgres: удалить ключ jsonb в рекурсивной функции слияния - PullRequest
0 голосов
/ 04 ноября 2018

Я пытаюсь добавить поддержку удаления ключа в jsonb, когда задаю значение «__delete __».

Я нашел хорошую функцию для объединения ключей здесь: http://blog.bguiz.com/2017/json-merge-postgresql/ Однако он не поддерживает удаление ключей из объектов. Вот оно:

CREATE OR REPLACE FUNCTION "public"."jsonb_merge_recurse"("orig" jsonb, "delta" jsonb)
  RETURNS "pg_catalog"."jsonb" AS $BODY$
    select
        jsonb_object_agg(
            coalesce(keyOrig, keyDelta),
            case
                when valOrig isnull then valDelta
                when valDelta isnull then valOrig
                when (jsonb_typeof(valOrig) <> 'object' or jsonb_typeof(valDelta) <> 'object') then valDelta
                else jsonb_merge_recurse(valOrig, valDelta)
            end
        )
    from jsonb_each(orig) e1(keyOrig, valOrig)
    full join jsonb_each(delta) e2(keyDelta, valDelta) on keyOrig = keyDelta
$BODY$
  LANGUAGE sql VOLATILE
  COST 100

Я хотел бы удалить ключ из объекта, в случае, если valDelta = '__delete __'.

Любая помощь высоко ценится, спасибо! :)

1 Ответ

0 голосов
/ 08 ноября 2018

В настоящее время "__deleted__" приводит к проблемам с некоторыми механизмами синтаксического анализа в PostgreSQL. Я бы рекомендовал использовать NULL для представления удаленного значения. С учетом сказанного вы могли бы упростить функцию, чтобы она была такой:

CREATE OR REPLACE FUNCTION "public"."jsonb_merge"("orig" jsonb, "delta" jsonb)
    RETURNS "pg_catalog"."jsonb" AS
    $$
      SELECT jsonb_strip_nulls($1 || $2);
    $$
    LANGUAGE SQL IMMUTABLE;

Оператор || объединяет два объекта JSONB вместе и задает предпочтения для любой пары ключ-значение, которая находится справа. Функция jsonb_strip_nulls удалит все ключи, с которыми связано значение null (И обратите внимание: null в JSONB трактуется иначе, чем SQL NULL, выполнение теста IS NULL / IS NOT NULL на JSONB null не будет работать).

Это не обрабатывает вложенные объекты JSON, но будет достаточно, если у вас есть только пары ключ-значение верхнего уровня.

...