使用 PostgreSQL 更新 NESTED JSONB 数组中的对象

Update objects inside NESTED JSONB arrays with PostgreSQL

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",
                "z4": [{
                    "name": "john"
                }]
            },
            {
                "id": "RO",
                "z2": false,
                "z3": "SELECT",
                "z4": [{
                    "name": "salin"
                }]
            }
        ]
    }
}'::jsonb)

我想根据 id "id" 更新归档的 z4: "RO".

当我需要更新 x3 字段(但没有任何过滤条件)时,我在这里有类似的用例 我用过:

UPDATE test.demotbl SET details = jsonb_set(data, '{x3}', [{"x_id": "sam"},{"x_id": "Rohit"}])

请求更新成功。 输出:

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

我有类似的用例,现在我还需要根据 id 值更新 z4 文件,问题是 z4 元素是嵌套的,而且我不知道如何放置过滤条件。

问题:我如何 add/update id 为 RW 的 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",
                "z4": [{
                    "name": "john"
                },
                {
                    "name": "Sandy"
                }]
            },
            {
                "id": "RO",
                "z2": false,
                "z3": "SELECT",
                "z4": [{
                    "name": "salin"
                }]
            }
        ]
    }
}

如果我正确理解你的问题,你可以使用类似这样的方法将字段 z3 更新为 'UPDATE' 例如:

with zd as (select ('{x4,y1,'||index-1||',z3}')::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('UPDATE'::text),false)
from zd                                     

这假定 jsonb 对象存储在 table1 中,在 jsonb 类型的字段 1 中。 它还假设 table.

中只有这一条记录

此代码取自https://www.freecodecamp.org/news/how-to-update-objects-inside-jsonb-arrays-with-postgresql-5c4e03be256a/并进行了调整。

此致,
比亚尼