使用PostgreSQL在嵌套JSONB数组中添加/更新对象和元素

使用PostgreSQL在嵌套JSONB数组中添加/更新对象和元素,postgresql,jsonb,Postgresql,Jsonb,Json请求: INSERT INTO test.demotbl (data) VALUES ('{ "x1": "Americas", "x2": "West", "x3": [{ "x_id": "sam" }], "x4": { "a1": true, "a2": false, "a3": [ "xx", "xx" ],

Json请求:

INSERT INTO test.demotbl (data)
VALUES ('{
    "x1": "Americas",
    "x2": "West",
    "x3": [{
        "x_id": "sam"
    }],
    "x4": {
        "a1": true,
        "a2": false,
        "a3": [
            "xx",
            "xx"
        ],
        "a4": [
            "Josh"
        ],
        "y1": [{
                "id": "RW",
                "z2": true,
                "z3": "USER"

            },
            {
                "id": "RO",
                "z2": false,
                "z3": "SELECT"

            }
        ]
    }
}'::jsonb)
我想根据id“id”:“RO”更新文件z4

当我需要更新下面查询中使用的z4字段时,我在这里有类似的用例:

with zd as (select ('{x4,y1,'||index-1||',z4}')::text[] as path
            from table1
            ,jsonb_array_elements((field1->>'x4')::jsonb->'y1') 
            with ordinality arr(x,index)
            where x->>'id'='RO'
        )
update table1
set field1=jsonb_set(field1,zd.path,to_jsonb('[ { "name": "john" } ]'::jsonb),false)
from zd
但现在在当前的json中,文件X4不存在,我需要添加“z4”:[{ “姓名”:“约翰” }而不仅仅是更新字段

预期产出:

{
    "x1": "Americas",
    "x2": "West",
    "x3": [{
        "x_id": "sam"
    }],
    "x4": {
        "a1": true,
        "a2": false,
        "a3": [
            "xx",
            "xx"
        ],
        "a4": [
            "Josh"
        ],
        "y1": [{
                "id": "RW",
                "z2": true,
                "z3": "USER"

            },
            {
                "id": "RO",
                "z2": false,
                "z3": "SELECT",
                "z4": [{
                    "name": "john"
                }]
            }
        ]
    }
}

上面的查询是否可以修改或建议一个新的查询用于add(如果没有字段z4)和update field z4示例“z4”:[{“name”:“john”},{“name”:“Steve”}]如果存在字段z4。

如果要添加z4,只需将jsonb_set函数中的最后一个参数更改为“true”,而不是“false”。这指示函数在字段不存在时创建该字段。 您需要将to_jsonb(…)更改为“…”::jsonb以解析数组。
这应该起作用:

with zd as (select ('{x4,y1,'||index-1||',z4}')::text[] as path
            from table1
            ,jsonb_array_elements((field1->>'x4')::jsonb->'y1') 
            with ordinality arr(x,index)
            where x->>'id'='RO'
        )
update table1
set field1=jsonb_set(field1,zd.path,'[{ "name": "john" },{ "name": "Steve" }]'::jsonb,true)
from zd
我希望我在这里正确地粘贴和修改了它:-)
致以最诚挚的问候,

Bjarni

z4:[{“name”:“john”,“name”:“steve”}]在预期的输出中看起来不同。是否希望z4成为数组?@Bjarni Ragnarsson是的,很抱歉输入错误,它应该是“z4”:[{“name”:“john”},{“name”:“steve”}]