Postgres:在递归合并功能中删除jsonb键

时间:2018-11-04 20:16:12

标签: sql json postgresql plpgsql

在将值设置为“ __delete__”时,我试图添加对删除jsonb中的键的支持。

我在这里发现了一个很好的合并键的功能: 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 :(得分:1)

当前"__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值的键(并注意:JSONB is treated differently than a SQL NULL中的null,因此请执行IS NULL / {{ 1}}在JSONB IS NOT NULL上进行测试将无效)。

这不处理嵌套的JSON对象,但是如果您只有顶级键/值对就足够了。