简体   繁体   English

如何更新嵌套 json Postgres 中的值

[英]How to update value in nested json Postgres

I have following JSON stored in "Info" column我在“信息”列中存储了以下 JSON

{
  "customConfig": {
    "isCustomGoods": 1
  },
  "new_addfields": {
    "data": [
      {
        "val": {
          "items": [
            {
              "Code": "calorie",
              "Value": "365.76"
            },
            {
              "Code": "protein",
              "Value": "29.02"
            },
            {
              "Code": "fat",
              "Value": "23.55"
            },
            {
              "Code": "carbohydrate",
              "Value": "6.02"
            },
            {
              "Code": "spirit",
              "Value": "1.95"
            }
          ],
          "storageConditions": "",
          "outQuantity": "100"
        },
        "parameterType": "Nutrition",
        "name": "00000000-0000-0000-0000-000000000001",
        "label": "1"
      },
      {
        "name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
        "val": "true"
      }
    ]
  }
}

I want to update value of nested json我想更新嵌套 json 的值

{
  "name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
  "val": "true"
}

and set "val"to "Yes" str so the result should be like并将“val”设置为“Yes” str 所以结果应该是这样的

{
  "name": "b4589168-5235-4ec5-bcc7-07d4431d14d6_Для ресторанов",
  "val": "Yes"
}

How can i do that ?我怎样才能做到这一点 ? Assuming that i need to update this value in json for many records in database假设我需要在 json 中为数据库中的许多记录更新此值

We can use jsonb_set() which is available from Postgres 9.5+我们可以使用 Postgres 9.5+ 提供的jsonb_set()

From Docs :文档

jsonb_set(target jsonb, path text[], new_value jsonb [, create_missing boolean])

Query to update the nested object:查询更新嵌套对象:

UPDATE temp t
SET info = jsonb_set(t.info,'{new_addfields,data,1,val}', jsonb '"Yes"')
where id = 1;

It can also be used in select query:它也可以用于选择查询:

SELECT 
  jsonb_set(t.info,'{new_addfields,data,1,val}', jsonb '"Yes"')
FROM temp t
LIMIT 1;

Considering you have a constant JSON Structure and a primary key in your table.考虑到您的表中有一个常量 JSON 结构和一个主键。 Idea is to get the exact path of element val having value true (which can be at any index in the array) then replace it with desired value.想法是获取值为true的元素val的确切路径(可以位于数组中的任何索引处),然后将其替换为所需的值。 So you can write your query like below:所以你可以像下面这样写你的查询:

with cte as (
select 
  id, 
  ('{new_addfields,data,'||index-1||',val}')::text[] as json_path
from 
  test, 
  jsonb_array_elements(info->'new_addfields'->'data') 
  with ordinality arr(vals,index) 
where 
  arr.vals->>'val' ilike 'true'
  )

 update test 
 set info = jsonb_set(info,cte.json_path,'"Yes"',false) 
 from cte 
 where test.id=cte.id;

DEMO 演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM