web-dev-qa-db-ja.com

json配列からオブジェクトを削除する方法は?

私のテーブル:

CREATE TABLE items (
    id BIGINT PRIMARY KEY NOT NULL,
    name VARCHAR,
    images json
);

画像フォーマット:

[
  {
    "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>"
  }
]

私はこのようなものが必要です:

UPDATE items SET images = delete(images, 'note_1');
3
TSK

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);
_

SQLフィドル

説明する

  1. セットを返す関数に暗黙の_JOIN LATERAL_を使用して、サブクエリでjson_array_elements()を使用してJSON配列のネストを解除します。詳細:
  2. ベーステーブルにJOINし、json_array_length()を使用して別のWHERE条件を追加して、影響を受けない行を除外します。これにより、テーブルのすべての行を更新しなくなります。スプレッド)ナンセンス。

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;_

はるかに速いである冒頭で影響を受けていない行を排除します。さらに、jsonbについても 広範なネイティブインデックスのサポート が追加されました。

いくつかの例、ベンチマーク、および新機能と古いjsonおよびMongoDBの比較、およびOutlookへの jsquery の主な作成者であるAlexander Korotkov、Oleg Bartunov、およびTeodor Sigaevat PGCon 2014による(一部):

4