如何从json数组中删除对象?

TSK*_*TSK 5 postgresql postgresql-9.3 json

我的表:

CREATE TABLE items (
    id BIGINT PRIMARY KEY NOT NULL,
    name VARCHAR,
    images json
);
Run Code Online (Sandbox Code Playgroud)

图片格式:

[
  {
    "id": "owner",
    "full": "<url>",
    "thumb": "<url>"
  },
  {
    "id": "note_0",
    "full": "<url>",
    "thumb": "<url>"
  },
  {
    "id": "note_1",
    "full": "<url>",
    "thumb": "<url>"
  },
  {
    "id": "note_2",
    "full": "<url>",
    "thumb": "<url>"
  }
]
Run Code Online (Sandbox Code Playgroud)

我需要这样的东西:

UPDATE items SET images = delete(images, 'note_1');
Run Code Online (Sandbox Code Playgroud)

Erw*_*ter 9

从列中删除所有元素images(保存一个 json 数组),其中'id''note_1'

第 9.3 页

UPDATE items i
SET    images = i2.images
FROM  (
  SELECT id, array_to_json(array_agg(elem)) AS images
  FROM   items i2
       , json_array_elements(i2.images) elem
  WHERE  elem->>'id' <> 'note_1'
  GROUP  BY 1
  ) i2
WHERE  i2.id = i.id
AND    json_array_length(i2.images) < json_array_length(i.images);
Run Code Online (Sandbox Code Playgroud)

SQL小提琴。

解释

  1. json_array_elements()使用隐式JOIN LATERAL的 set-returning 函数在子查询中取消嵌套 JSON 数组。细节:
  2. 加入基表并添加另一个WHERE条件json_array_length()用于排除未受影响的行 - 这样您就不会更新表的每一行,这将是昂贵的(并且广泛传播的)废话。

第 9.4 页

使用jsonb附加jsonb运算符,这会变得容易得多。


UPDATE items i
SET    images = i2.images
FROM  (
  SELECT id, array_to_json(array_agg(elem)) AS images
  FROM   items cand
       , json_array_elements(cand.images) elem
  WHERE  cand.images @> '{[{"id":"note_1"}]}'::jsonb
  AND    elem->>'id' <> 'note_1'
  GROUP  BY 1
  ) i2
WHERE i2.id = i.id;
Run Code Online (Sandbox Code Playgroud)

在开始时消除未受影响的行,这要快得多。此外,还有大量的原生指数支持jsonb,太,现在。

这里有一些例子,基准和新的功能,以老JSON和MongoDB,加上前景比较jsquery的(一些),他们的主要作者,亚历山大·科罗特科夫,奥列格Bartunov andTeodor Sigaevat PGCon 2014:

  • 你是个巫师埃尔文 (2认同)