POSTGRESQL:如果 key:value 不存在则更新 jsonb

POSTGRESQL: update jsonb if key:value doesn't exsits

我想更新 table 中的一个 jsonb 列(示例):

CREATE TEMPORARY TABLE tmp_1 AS
SELECT 1 as id,'{"foo":1,"bar":2,"foo_bar":3}'::jsonb as jb_value;

这次更新的方式:

UPDATE tmp_1 
   SET jb_value = jb_value || '{"foo_bar":4, "foo_foo_bar":4}'
 WHERE id = 1;

会 return 类似于 :

Result:
{"foo":1,"bar":2,"foo_bar":[3,4],"foo_foo_bar":4}

|| 运算符对我不起作用,因为根据 docs:

Note: The || operator concatenates two JSON objects by generating an object containing the union of their keys, taking the second object's value when there are duplicate keys. All other cases produce a JSON array: first, any non-array input is converted into a single-element array, and then the two arrays are concatenated. It does not operate recursively; only the top-level array or object structure is merged.

这会 return 替换键 "foo_bar" 的值, 我不想要

Result:
{"foo":1,"bar":2,"foo_bar":4,"foo_foo_bar":4}

我还考虑了 jsonb_insertjsonb_set,但我不知道要更新或插入的密钥的路径。

提前致谢!

试试这个:

SELECT jsonb_object_agg( COALESCE(a.key, b.key)
                       , CASE
                             WHEN a.key IS NULL THEN b.value
                             WHEN b.key IS NULL THEN a.value
                             ELSE '[]' :: jsonb || a.value || b.value
                         END
                       )
  FROM jsonb_each('{"foo":1,"bar":2,"foo_bar":3}'::jsonb) AS a
  FULL OUTER JOIN jsonb_each('{"foo_bar":4, "foo_foo_bar":4}' :: jsonb) AS b
     ON a.key = b.key

http://sqlfiddle.com/#!17/9eecb/84825

您可以将此查询插入到您的 UPDATE 语句中。