使用特定键更新Postgres中的JSON数组

使用特定键更新Postgres中的JSON数组,json,postgresql,jsonb,Json,Postgresql,Jsonb,我有一个复杂的数组,在表列中如下所示: { "sometag": {}, "where": [ { "id": "Krishna", "nick": "KK", "values": [ "0" ], "function

我有一个复杂的数组,在表列中如下所示:

{
"sometag": {},
"where": [
    {
        "id": "Krishna",
        "nick": "KK",
        "values": [
            "0"
        ],
        "function": "ADD",
        "numValue": [
            "0"
        ]
    },
    {
        "id": "Krishna1",
        "nick": "KK1",
        "values": [
            "0"
        ],
        "function": "SUB",
        "numValue": [
            "0"
        ]
    }
],
"anotherTag": [],
"TagTag": {
    "tt": "tttttt",
    "tt1": "tttttt"
}
在这个数组中,我想更新id“Krishna”的函数和numValue


请帮忙。

这真的很糟糕,因为

  • 更新JSON数组中的元素始终需要扩展数组
  • 顶部:数组是嵌套的
  • 要更新的元素的标识符是同级而不是父级,这意味着您必须按同级进行筛选
  • 所以我提出了一个解决方案,但我想声明:您应该避免将此作为常规数据库操作来执行!最好是:

  • 在后端解析JSON并在后端代码中执行操作
  • 规范化数据库中的JSON(如果这是一项常见任务),这意味着:创建具有适当列的表,并将JSON提取到表结构中。不要在数据库中存储整个JSON对象!这将使每一项任务都变得更简单、更出色

  • 将嵌套数组元素提取到每行一个元素中
  • 替换
    功能
    值。注意从type
    json
    到type
    jsonb
    的强制转换。这是必要的,因为没有
    json\u set()
    函数,只有
    jsonb\u set()
    。当然,如果您只有类型
    jsonb
    ,则不需要强制转换
  • 替换
    numValue
    value
  • 重新聚集阵列
  • 用新创建的数组对象替换原始JSON对象的
    where

  • 到目前为止你试过什么?你的预期产出是多少?为什么numValue是数组?numValue可以有多个值。预期输出:{“sometag”:{},其中:[{“id”:“Krishna”,“nick”:“KK”,“values”:[“0”],“function”:“ADDITION”,“numValue”:[“0”,“1”]},{“id”:“Krishna1”,“nick”:“kkk1”,“values”:[“0”],“function”:“SUB”,“numValue”:[“0”}],“anotherTag”:[“tag”:{“tt”:“tttttt”,“tt1”:“tttttt”}}使用正确规范化的数据模型,这会容易得多
    SELECT
        jsonb_set(                                                                                -- 5
            (SELECT mydata::jsonb FROM mytable), 
            '{where}', 
            updated_array
        )::json
    FROM (
        SELECT
            jsonb_agg(                                                                            -- 4
                CASE WHEN array_elem ->> 'id' = 'Krishna' THEN
                    jsonb_set(                                                                    -- 3
                        jsonb_set(array_elem.value::jsonb, '{function}', '"ADDITION"'::jsonb),    -- 2
                        '{numValue}', 
                        '["0","1"]'::jsonb
                    )
                ELSE array_elem::jsonb END
            ) as updated_array
        FROM mytable,
            json_array_elements(mydata -> 'where') array_elem                                     -- 1
    ) s