【问题标题】:Update JSON Array in Postgres with specific key使用特定键更新 Postgres 中的 JSON 数组
【发布时间】:2021-04-26 15:17:24
【问题描述】:

我有一个复杂的数组,在表格列中如下所示:

{
"sometag": {},
"where": [
    {
        "id": "Krishna",
        "nick": "KK",
        "values": [
            "0"
        ],
        "function": "ADD",
        "numValue": [
            "0"
        ]
    },
    {
        "id": "Krishna1",
        "nick": "KK1",
        "values": [
            "0"
        ],
        "function": "SUB",
        "numValue": [
            "0"
        ]
    }
],
"anotherTag": [],
"TagTag": {
    "tt": "tttttt",
    "tt1": "tttttt"
}

在这个数组中,我想更新 id: "Krishna" 的函数和 numValue。

请帮忙。

【问题讨论】:

  • 到目前为止你尝试过什么?你的预期输出是什么?为什么 numValue 是一个数组?
  • numValue 可以有多个值。期望输出:{“sometag”:{},“where”:[{“id”:“Krishna”,“nick”:“KK”,“values”:[“0”],“function”:“ADDITION” , "numValue": [ "0","1" ] }, { "id": "Krishna1", "nick": "KK1", "values": [ "0" ], "function": "SUB" , "numValue": [ "0" ] } ], "anotherTag": [], "TagTag": { "tt": "tttttt", "tt1": "tttttt" } }
  • 使用正确规范化的数据模型会容易得多

标签: json postgresql jsonb


【解决方案1】:

这真的很讨厌,因为

  1. 更新 JSON 数组中的元素总是需要扩展数组
  2. 置顶:数组是嵌套的
  3. 要更新的元素的标识符是同级而不是父级,这意味着您必须按同级进行过滤

所以我想出了一个解决方案,但我想声明:您应该避免将其作为常规数据库操作!更好的是:

  1. 在后端解析 JSON 并在后端代码中执行操作
  2. 如果这是一项常见任务,请对数据库中的 JSON 进行规范化,这意味着:创建具有适当列的表并将 JSON 提取到表结构中。不要将整个 JSON 对象存储在数据库中!这样一来,每一项任务都会变得更加轻松,而且性能更加出色!

demo:db<>fiddle

SELECT
    jsonb_set(                                                                                -- 5
        (SELECT mydata::jsonb FROM mytable), 
        '{where}', 
        updated_array
    )::json
FROM (
    SELECT
        jsonb_agg(                                                                            -- 4
            CASE WHEN array_elem ->> 'id' = 'Krishna' THEN
                jsonb_set(                                                                    -- 3
                    jsonb_set(array_elem.value::jsonb, '{function}', '"ADDITION"'::jsonb),    -- 2
                    '{numValue}', 
                    '["0","1"]'::jsonb
                )
            ELSE array_elem::jsonb END
        ) as updated_array
    FROM mytable,
        json_array_elements(mydata -> 'where') array_elem                                     -- 1
) s
  1. 将嵌套数组元素提取为每行一个元素
  2. 替换function 值。注意从json 类型到jsonb 类型的转换。这是必要的,因为没有json_set() 函数,只有jsonb_set()。当然,如果您只有 jsonb 类型,则不需要强制转换。
  3. 替换numValue
  4. 重新聚合数组
  5. 将原始 JSON 对象的 where 值替换为新创建的数组对象。

【讨论】:

    猜你喜欢
    • 2019-04-01
    • 2018-05-01
    • 1970-01-01
    • 2022-08-13
    • 2021-03-26
    • 1970-01-01
    • 2018-03-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多