【问题标题】:How to add a new key-value pair in jsonb without creating a new object? (Postgres)如何在不创建新对象的情况下在 jsonb 中添加新的键值对? (Postgres)
【发布时间】:2021-05-05 09:01:48
【问题描述】:

我需要在现有的 json 对象中添加一个新的键值对。将不胜感激。

json:

{
  "json_col": [
    {
      "val1": 1,
      "val2": 0,
      "val3": "qwe"
    }
  ]
}

我想出了这个查询

UPDATE table SET  
json_col = jsonb_set(
    json_col, 
    '{json_col}', json_col->'json_col' || '{"test":123}'))
where id=6400

它会输出:

{
  "json_col": [
    {
      "val1": 1,
      "val2": 0,
      "val3": "qwe"
    },
    {
      "test": 123
    }
  ]
}

但是我需要这个 json 是一个单一的对象(没有额外的括号),像这样:

{
  "json_col": [
    {
      "val1": 1,
      "val2": 0,
      "val3": "qwe",
      "test": 123
    }
  ]
}

【问题讨论】:

  • 您的 PostgreSQL 服务器的版本是什么? json_col 是一个数组 - 你想更新哪个元素?
  • @JuliusTuskenis 12.6,是的,没错,我想更新对象,它是 json_col 数组中的一个元素
  • 我认为数组中可能有几个元素。那么你想更新哪个元素:数组中的一个特定元素还是所有元素?
  • 这个数组只有一个元素,所以我只想更新一个元素

标签: json postgresql jsonb


【解决方案1】:

您的语法基本正确,您只需更正 pathjsonb_set 提供的值并提取 json_col 元素的第一个元素:

UPDATE some_table SET  
  json_col = jsonb_set(
    json_col::jsonb, 
    '{json_col,0}', 
    (json_col->'json_col'->0)||'{"test":123}'
  )::json
where id=6400;

你可以测试它:db<>fiddle

数组中的多个元素

如果您的 json_col 数组包含多个元素,并且您希望使用相同的键:值对更新每个元素,则应该使用此查询:

UPDATE some_table SET  
  json_col = jsonb_set(
    json_col, 
    '{json_col}', 
    (SELECT jsonb_agg(elem||'{"test":123}') 
       FROM jsonb_array_elements( json_col->'json_col') AS elem ) 
  )
where id=6400;

db<>fiddle

【讨论】:

  • 很好,它有效,谢谢,但我实际上错了 - 数组中可以有多个元素,那么如果有多个元素,它应该怎么看?
  • 更新了答案。
  • 其实key是一样的,但是value会不一样
  • 如果是这样,您必须将键值的来源加入到jsonb_array_elements( json_col-&gt;'json_col') as elem 部分,然后使用 jsonb_build_object 而不是常量'{"test":123}'。如果你想要完整的例子,你应该提供构建测试用例所需的所有数据(最好是 SQL 语句的形式)和预期的结果。
猜你喜欢
  • 2012-04-14
  • 1970-01-01
  • 2014-06-09
  • 1970-01-01
  • 1970-01-01
  • 2022-11-30
  • 2013-04-25
  • 2018-08-02
  • 2021-08-06
相关资源
最近更新 更多