【问题标题】:Update a complex JSONB object to remove a sub-sub-property with a PostgreSQL query使用 PostgreSQL 查询更新复杂 JSONB 对象以删除子子属性
【发布时间】:2021-02-03 07:01:18
【问题描述】:

假设我在 my_jsonb PostgreSQL 数据库表的列中有这样的 JSONB 数据,模式如下:

[
  {
    "foo": {
      "bar": [
        {
          "baz": 1,
          "qux": 2
        }
      ]
    }
  },
  {
    "foo": {
      "bar": [
        {
          "baz": 3,
          "qux": 4
        },
        {
          "baz": 5,
          "qux": 6
        }
      ]
    }
  }
]

换言之,my_jsonb 的每一列都有一个 foo 列表,该列表具有一个属性 bar,其中包含具有两个属性 bazqux 的对象数组。

我现在认为 baz 属性已过时,我想将其删除以拥有此:

[
  {
    "foo": {
      "bar": [
        {
          "qux": 2
        }
      ]
    }
  },
  {
    "foo": {
      "bar": [
        {
          "qux": 4
        },
        {
          "qux": 6
        }
      ]
    }
  }
]

我可以使用脚本在每个bar 项目中一个一个地删除这些baz 属性,但它会超长。有没有办法更新复杂的 JSONB 对象以删除子子属性而不用脚本做任何事情?

可以逐行进行(我的实际表中只有 100k 行,所以我认为迭代每一行是安全的,我唯一想要的就是 删除所有 baz属性在一行中一次)。

有可能吗?

【问题讨论】:

    标签: sql postgresql jsonb


    【解决方案1】:

    如果 json 结构是刚性的,您可以通过以下方式重新创建 json 对象:

    select id, jsonb_agg(new_foos order by fo)
    from (
        select 
            id, fo, 
            jsonb_build_object(
                'foo', 
                jsonb_build_object(
                    'bar', 
                    jsonb_agg(bars- 'baz' order by bo))
            ) as new_foos
        from my_table
        cross join 
            jsonb_array_elements(json_data) 
            with ordinality as foos(foos, fo)
        cross join 
            jsonb_array_elements(foos->'foo'->'bar') 
            with ordinality as bars(bars, bo)
        group by id, fo
        ) s
    group by id
    

    请注意,我们使用具有 with ordinality 功能获得的顺序的聚合来保留数组元素的原始顺序。

    Db<>Fiddle.

    【讨论】:

    • 还有一个问题:两个数组的顺序都保证了吗?
    • 再次感谢您!也许您可以通过添加“替代”版本来更新您的帖子,并在原始版本之后保留顺序?它可以帮助其他读者找到合适的解决方案。如果你愿意,我也可以自己做。谢谢!
    猜你喜欢
    • 2016-01-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-27
    相关资源
    最近更新 更多