如何在Postgres中的JSONB字段中编辑JSON对象深处的单个值?

如何在Postgres中的JSONB字段中编辑JSON对象深处的单个值?,json,postgresql,Json,Postgresql,因此,我们在Postgres中有一个类似于的Jsonb字段 { "entity":[ { "id":"1234", "data":[ { "docId":"123456", "status":"PENDING&q

因此,我们在Postgres中有一个类似于的Jsonb字段

{
   "entity":[
      {
         "id":"1234",
         "data":[
            {
               "docId":"123456",
               "status":"PENDING"
            },
            {
               "docId":"123457",
               "status":"PENDING"
            },
            {
               "docId":"123458",
               "status":"PENDING"
            }
         ]
      }
   ]
}
我希望将文档id为123457的数据对象更新为已解决状态。在不影响其他状态的情况下。我怎样才能在博士后做到这一点


我们最初的想法是读取整个文档,然后从Java重写JSON对象并重新保存,但该解决方案会导致争用错误,因为对文档id 123456的并行操作会在调用123457之前几毫秒停止。所以我想,如果用SQL处理Json操作,它可能会解决这个问题。

您的根本问题是一个糟糕的数据模型。如果您没有将这些数据存储为单个JSON,而是存储在具有多个表和外键关系的规范化数据库模型中,那么这个练习将是微不足道的

您可以在SQL中实现这一点,但这本质上意味着将JSON解包成表格数据,使用jsonb_集修改JSON并重建整个过程,这需要几个横向连接,对我来说太复杂了

如果更容易的话,可以在客户端进行。很容易防止比赛条件:

一个选项是使用选择。。。用于在您打算修改数据时进行更新。然后,两个这样的选择将相互锁定,第二个选择将不得不等待,直到第一个事务完成

另一种选择是使用更高的事务隔离级别,在本例中为可重复读取。然后,当第二个事务修改数据并且必须重试该事务时,它将获得序列化错误


假设您的表名为foo和jsonb字段栏,您可以执行以下操作:

具有 e作为SELECT元素,索引-1作为i 来自foo,jsonb_数组_元素sbar->“实体” 带序数的o元素,索引 其中元素->>'id'='1234', 选择idx-1作为i 来自e,jsonb_数组_元素选择->数据 带序数o元素,idx 其中elem->>“docId”=“123457” 更新foo 设置杆=jsonb_立根杆, 数组['entity',e.i::text,'data',f.i::text,'status'], “已解决”, 错误的 从e,f 其中bar->'entity'->e.i::int->'id'='1234';
但是,正如这里的其他人所说,你应该真正将你的数据转换成一个关系模型,而不是像对待表一样对待JSON:o

规范化你的数据模型,问题就会消失。我会尝试一下,但是JSON中的数据模型在工作中是固定不变的。