Postgres/JSON 更新嵌套数组元素

问题描述

给定来自名为 '_value' 的列下的 'table' 的输入 JSON。我想将字段“sc”替换为从对象到 sc 下名称值的文本。

更新前的json是这样的。

{
    "iProps": [
    {
        "value": {
            "rules": [
                {
                    "ao": {
                        "sc": {
                            "web_link": "abc.com","name": "name"
                        }
                    }
                },{
                    "ao": {
                        "sc": ""
                    }
                }
            ]
        }
    }
]
}

更新后的json应该是这样的。

{
    "iProps": [
    {
        "value": {
            "rules": [
                {
                    "ao": {
                        "sc":  "name"
                    }
                },{
                    "ao": {
                        "sc": ""
                    }
                }
            ]
        }
    }
]
}

我尝试了以下查询获取“规则”数组,但在解析和更新方面难以进一步进行。

 WITH values AS (
    SELECT iprop -> 'value' -> 'rules' AS value FROM
    table t,jsonb_array_elements(t._value->'iProps') AS 
        iprop )
SELECT *
from values,jsonb_array_elements(values.ao)

抛出以下错误

ERROR:  column values.ao does not exist
LINE 26: from values,jsonb_array_elements(values.ao)
                                           ^
sql state: 42703
Character: 1396

解决方法

考虑到您的结构是常量并且列的数据类型是 JSONB,您可以尝试下面提到的查询。

with cte as (
select 
 vals2->'ao'->'sc'->'name' as namevalue,('{iProps,'||index1-1||',value,rules,'||index2-1||',ao,sc}')::text[] as json_path
from 
  table_,jsonb_array_elements(value_->'iProps') 
  with ordinality arr1(vals1,index1),jsonb_array_elements(vals1->'value'->'rules') 
  with ordinality arr2(vals2,index2)

  )

 update table_ 
 set value_ = jsonb_set(value_,cte.json_path,cte.namevalue,false) 
 from cte
WHERE cte.namevalue IS NOT NULL

DEMO