4

元のstackoverflow questionを参照して、Postgres 9.4の配列のオブジェクトのキーにginインデックスを適用しようとしていますが、最初の回答に記載されている結果が得られません。

エラーを修正していただけますか?

私が従った手順は以下に書かれています。

パート 1: テーブルとインデックスの作成

CREATE TABLE tracks (id serial, artists jsonb);
CREATE INDEX tracks_artists_gin_idx ON tracks USING gin (artists);
INSERT INTO tracks (id, artists) VALUES (1, '[{"name": "blink-182"}]');
INSERT INTO tracks (id, artists) VALUES (2, '[{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]');

パート 2: クエリ

SELECT * FROM tracks WHERE artists @> '{"name": "The Dirty Heads"}';
 id | artists 
----+---------
(0 rows)

このクエリは空の結果を返します。また、 GIN インデックス
を使用しようとしました。jsonb_path_ops

代替インデックスとクエリ:

DROP INDEX tracks_artists_gin_idx;
CREATE INDEX tracks_artistnames_gin_idx ON tracks USING  gin (artists jsonb_path_ops);
SELECT * FROM tracks WHERE artists @> '{"name": "The Dirty Heads"}';
 id | artists 
----+---------
(0 rows)
4

1 に答える 1

7

元の回答からのこの特定の jsonb の例[]には、格納クエリの非プリミティブ オブジェクトの周りの配列レイヤーがありませんでした。その後、修正されました。

PostgreSQL 9.4.x jsonb Containment and Existenceについて文書化された動作は次のように述べています。

一般的な原則は、構造とデータの内容に関して、含まれるオブジェクトが含まれるオブジェクトと一致する必要があるということです。

...

構造が一致しなければならないという一般原則の特別な例外として、配列にはプリミティブ値が含まれる場合があります。

特別な例外により、次のことが可能になります。

CREATE TABLE tracks (id serial, artistnames jsonb);
CREATE INDEX tracks_artistnames_gin_idx ON tracks USING gin (artistnames);
INSERT INTO tracks (id, artists) VALUES (1, '["blink-182"]');
INSERT INTO tracks (id, artists) VALUES (2, '["The Dirty Heads", "Louis Richards"]');

一般原則を使用して封じ込めを照会できます。

SELECT * FROM tracks WHERE artistnames @> '["The Dirty Heads"]';
 id |              artistnames              
----+---------------------------------------
  2 | ["The Dirty Heads", "Louis Richards"]
(1 row)

配列にはプリミティブ型が含まれているため、特別な例外を使用して包含を照会することもできます。

SELECT * FROM tracks WHERE artistnames @> '"The Dirty Heads"';
 id |              artistnames              
----+---------------------------------------
  2 | ["The Dirty Heads", "Louis Richards"]
(1 row)

配列に対する包含クエリと存在クエリが機能するようにする 4 つのプリミティブ型があります。

  1. ストリング
  2. 番号
  3. ブール値
  4. ヌル

質問で言及した例は、配列内にネストされたオブジェクトを扱っているため、上記の特別な例外の対象にはなりません。

CREATE TABLE tracks (id serial, artists jsonb);
CREATE INDEX tracks_artists_gin_idx ON tracks USING gin (artists);
INSERT INTO tracks (id, artists) VALUES (1, '[{"name": "blink-182"}]');
INSERT INTO tracks (id, artists) VALUES (2, '[{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]');

一般原則を使用して封じ込めを照会できます。

SELECT * FROM tracks WHERE artists @> '[{"name": "The Dirty Heads"}]';
 id |                          artists                          
----+-----------------------------------------------------------
  2 | [{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]
(1 row)

オブジェクトはプリミティブ型とは見なされないため、包含に関する次のクエリは特別な例外に該当しないため、機能しません。

SELECT * FROM tracks WHERE artists @> '{"name": "The Dirty Heads"}';
 id | artists 
----+---------
(0 rows)
于 2015-04-29T14:48:39.203 に答える