微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

postgresql:更新一个 jsonb 对象中的多个值

如何解决postgresql:更新一个 jsonb 对象中的多个值

我最近在 Postgresql 数据库中遇到了一个关于 JSONB 数据类型的问题。

我的列有一个相当复杂的结构(假设该表名为 rating,列名为 FOOD_VALUE - 组成),例如,如下所示:

{
  "food": {
            "type": {
                     "id": 1,"name": "good"
                    },"category": {
                          "id": 2,"name": "vegetables"
                       },"others": {
                       "descr": "It's all good"
                     }
         }
}

这是一个示例,实际可能有多达数百个值(当然是嵌套的)。

我想在不修改结构本身的情况下更新几个值(在这个例子中是两个 -> food.type.name + food.category.id)。

这是所需的输出

{
  "food": {
            "type": {
                     "id": 1,"name": "not bad"
                    },"category": {
                          "id": 1,"others": {
                       "descr": "It's all good"
                     }
         }
}

使用 JSONB_SET 我只能操作同一列中的一条记录 -> rating.FOOD_VALUE ...我知道我也可以嵌套它们,但考虑到我需要更新 40 多个值,这可能会变得难以阅读(并因此维持)

所以:

UPDATE rating 
SET food_value = jsonb_set(
      jsonb_set(food_value,'{food,type,name}','"not bad"')::jsonb,category,id}','"1"'::jsonb)
WHERE ....

绝对不行..

实现此目的的另一种方法是使用 JSON_BUILD_OBJECT:

UPDATE rating 
SET food_value = food_value 
   || jsonb_build_object('food',jsonb_build_object('type',jsonb_build_object('name','not bad')))
   || jsonb_build_object('food',jsonb_build_object('category',jsonb_build_object('id',1)))
   ... and so on
WHERE ....

这在维护、可读性等方面看起来更有希望。但我在这里面临的问题是它改变了 JSON 文件格式的结构:( 所以上面的查询将导致

{
  "food": {
            "type": {
                      "name": "not bad"
                    },"category": {
                          "id": 1
                       }
         }
}

知道如何摆脱这种困境吗?我需要找到一种方法,如何在不修改结构本身(只是值)的情况下更新复杂 JSON 结构中的数十个字段

解决方法

create type t_json_val as (path text[],val jsonb);

create or replace function jsonb_mset(a jsonb,variadic b t_json_val[])
    returns jsonb
    immutable
    language plpgsql
as $$
-- Set multiple jsonb values at once
declare
    bb t_json_val;
begin
    foreach bb in array b loop
        a := jsonb_set(a,bb.path,bb.val);
    end loop;
    return a;
end $$;
select jsonb_pretty(jsonb_mset('{
  "food": {
            "type": {
                     "id": 1,"name": "good"
                    },"category": {
                          "id": 2,"name": "Vegetables"
                       },"others": {
                       "descr": "It''s all good"
                     }
         }
}',('{food,type,name}','"not bad"'),category,id}','"1"')));

┌──────────────────────────────────────┐
│             jsonb_pretty             │
├──────────────────────────────────────┤
│ {                                   ↵│
│     "food": {                       ↵│
│         "type": {                   ↵│
│             "id": 1,↵│
│             "name": "not bad"       ↵│
│         },↵│
│         "others": {                 ↵│
│             "descr": "It's all good"↵│
│         },↵│
│         "category": {               ↵│
│             "id": "1",↵│
│             "name": "Vegetables"    ↵│
│         }                           ↵│
│     }                               ↵│
│ }                                    │
└──────────────────────────────────────┘

demo

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?