如何更新 postgres 数组中的 json?

How to update json in postgres array?

我已附上 JSON 输入和输出

输入

{
  "cap1": [
    {
      "fe1": [
        {
          "par1": 0,
          "fet1": 6,
          "fun1": [
            {
              "fnd1": [
                {
                  "name": "v1",
                  "site": [
                    "w1",
                    "mb1",
                    "tb1"
                  ]
                }
              ]
            }
          ]
        }
      ],
      "capab1": 2
    },
    {
      "fe1": [
        {
          "par1": 0,
          "fet1": 42,
          "fun1": null
        },
        {
          "par1": 42,
          "fet1": 43,
          "fun1": null
        }
      ],
      "capab1": 11
    }
  ]
}

我想在 "capab1": 11.

中添加 {"par1": 0, "fet1": 44, "fun1": null},{"par1": 0, "fet1": 45, "fun1": null}

输出应该是

{
  "cap1": [
    {
      "fe1": [
        {
          "par1": 0,
          "fet1": 6,
          "fun1": [
            {
              "fnd1": [
                {
                  "name": "v1",
                  "site": [
                    "w1",
                    "mb1",
                    "tb1"
                  ]
                }
              ]
            }
          ]
        }
      ],
      "capab1": 2
    },
    {
      "fe1": [
        {
          "par1": 0,
          "fet1": 42,
          "fun1": null
        },
        {
          "par1": 42,
          "fet1": 43,
          "fun1": null
        },
        {
          "par1": 0,
          "fet1": 44,
          "fun1": null
        },
        {
          "par1": 0,
          "fet1": 45,
          "fun1": null
        }
      ],
      "capab1": 11
    }
  ]
}

有点复杂。您可以使用 jsonb_array_elements 取消嵌套数组并获取要更新的路径。然后使用 JSONB_INSERT 更新 JSON,如下所示: 这是解决方案:

with cte as (
select  *,
('{cap1,'||index1-1||',fe1,0}')::text[] as json_path
from test,
jsonb_array_elements(col->'cap1') with ordinality arr1 (vals1,index1)
where (vals1->>'capab1')::int=11
)
 update test 
 set col = jsonb_insert(test.col,cte.json_path,'[{"par1": 0, "fet1": 44, "fun1": null},{"par1": 0, "fet1": 45, "fun1": null}]'::jsonb,true) 
 from cte 
 where test.id=cte.id

DEMO