首页 > 解决方案 > 如何在 postgresql 10 中更新复杂 JSON 文档中的特定 JSON 元素

问题描述

我有JSON document它存储在jsonb里面的单个类型列下postgresql,如下所示:

{
  "resourceType": "Bundle",
  "type": "transaction",
  "entry": [
    {
      "fullUrl": "urn:uuid:100",
      "resource": {
        "resourceType": "Encounter",
        "id": "110",
        "status": "planned",
        "priority": {
          "coding": [
            {
              "code": "ASAP"
            }
          ]
        },
        "subject": {
          "reference": "Patient/123"
        },
        "appointment": [
          {
            "reference": "Appointment/12213#42"
          }
        ],
        "diagnosis": [
          {
            "condition": {
              "reference": "Condition/condReferenceValue"
            },
            "use": {
              "coding": [
                {
                  "system": "http://terminology.hl7.org/CodeSystem/diagnosis-role",
                  "code": "AD"
                },
                {
                  "system": "http://terminology.hl7.org/CodeSystem/diagnosis-role",
                  "code": "DD"
                }
              ]
            }
          }
        ],
        "hospitalization": {
          "preAdmissionIdentifier": {
            "system": "https://system.html"
          }
        },
        "location": [
          {
            "location": {
              "display": "Mumbai"
            },
            "status": "active"
          },
          {
            "status": "planned"
          }
        ]
      },
      "request": {
        "method": "POST",
        "url": "Encounter"
      }
    }
  ]
}  

现在,我想更新referenceundersubject属性的值。所以,我尝试了以下方式,但它抛出了一个错误:

update fhir.testing set names = jsonb_set(names,'{"subject":{"reference"','"Patient/1"',true) where id = 10;   

错误:

SQL Error [22P02]: ERROR: malformed array literal: "{"subject":{"reference""
  Detail: Unexpected array element.  

我提到了这个链接,但对我没有用。我该怎么做?

标签: jsonpostgresql

解决方案


我没有那么多使用 Postgres,但从我在JSON 函数jsonb_set文档中的相关示例中读到的内容(并且因为你想更新)不应该是

jsonb_set(names, '{entry,0,subject,reference}','Patient/1', false)

代替

jsonb_set(names,'{"subject":{"reference"','"Patient/1"',true)  

jsonb

jsonb_set(target jsonb, path text[], new_value jsonb [, create_missing boolean])

如果为true默认为 true)且 由 指定的项目不存在,则返回targetpath替换 new_value或添加的部分。与面向路径的运算符一样,出现的负整数从 JSON 数组的末尾开始计数。new_valuecreate_missing pathpath

编辑

要解释 in 中path使用的内容jsonb_set,请查看此示例。

jsonb_set('[{"f1":1,"f2":null},2,null,3]', '{0,f1}','[2,3,4]', false)

返回

[{"f1":[2,3,4],"f2":null},2,null,3]

据我了解,如果复杂 JSON 文档中的子元素是一个数组,您需要指定它的索引,例如 0,1,2,...

编辑

始终非常仔细地查看 JSON 文档的结构。我只是写这个,因为我没有看到那个主题资源的孩子,这导致了你的错误。

所以正确的路径实际上是'{entry,0,resource,subject,reference}'


推荐阅读