簡體   English   中英

如何刪除/更新鍵等於值的 JSONB 數組元素?

[英]How to remove/update a JSONB array element where key equals a value?

我想從屬性等於設定值的 JSONB 數組中刪除/替換一個元素。 我已經找到了許多可以完成此操作的功能,但我想知道是否有一種方法可以做到這一點,因為我有數據庫限制?

這是一個示例 JSONB 值:

[
  { "ID": "valuea" },
  { "ID": "valueb" },
  { "ID": "valuec" }
]

我想用一條更新語句刪除第二個數組 position,其中 ID 等於valueb 我想這可以找到數組中的位置/順序, jsonb_set()將其刪除。

如果有一種方法可以更新行而不僅僅是刪除它,那也會很有幫助。 可能是類似的查詢,再次使用jsonb_set()

不幸的是,從 Postgres 15 開始,沒有 function 返回 JSON 數組元素的 position(目前)。

要刪除單個匹配元素:

UPDATE tbl t
SET    js = t.js - (SELECT j.ord::int - 1
                    FROM   jsonb_array_elements(t.js) WITH ORDINALITY j(v,ord)
                    WHERE  j.v = '{"ID": "valueb"}'
                    LIMIT  1)
WHERE  t.js @> '[{"ID": "valueb"}]'   -- optional
AND    jsonb_typeof(t.js) = 'array';  -- optional

UPDATE使用與jsonb_array_elements()相關的子查詢。
關於WITH ORDINALITY

兩個WHERE子句都是可選的。

  • 使用過濾器t.js @> '[{"ID": "valueb"}]'來抑制(可能很昂貴!)空更新並充分利用jsonb列上的現有 GIN 索引

  • 使用過濾器jsonb_typeof(t.js) = 'array'只抑制來自非數組的錯誤。

請注意外部過濾器如何包含封閉的數組裝飾器[] ,而內部過濾器(在取消嵌套之后)不包含。

要刪除所有匹配元素:

UPDATE tbl t
SET    js = (SELECT jsonb_agg(j.v)
             FROM   jsonb_array_elements(t.js) j(v)
             WHERE  NOT j.v @> '{"ID": "valueb"}')
WHERE  t.js @> '[{"ID": "valueb"}]';

小提琴

第二個查詢從剩余元素聚合一個新數組。

這一次,內部過濾器使用@>而不是=來允許額外的鍵。 選擇合適的過濾器。

旁白:如果所討論的數組實際上是嵌套的,則jsonb_set()可能還有用,這與您的示例不同。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM