JSON配列内の要素を見つけるためのインデックス

ジェフS

私は次のようなテーブルを持っています:

CREATE TABLE tracks (id SERIAL, artists JSON);

INSERT INTO tracks (id, artists) 
  VALUES (1, '[{"name": "blink-182"}]');

INSERT INTO tracks (id, artists) 
  VALUES (2, '[{"name": "The Dirty Heads"}, {"name": "Louis Richards"}]');

この質問に関係のない他のいくつかの列があります。それらをJSONとして保存するのには理由があります。

私がやろうとしているのは、特定のアーティスト名(完全一致)を持つトラックを検索することです。

私はこのクエリを使用しています:

SELECT * FROM tracks 
  WHERE 'ARTIST NAME' IN
    (SELECT value->>'name' FROM json_array_elements(artists))

例えば

SELECT * FROM tracks
  WHERE 'The Dirty Heads' IN 
    (SELECT value->>'name' FROM json_array_elements(artists))

ただし、これは全表スキャンを実行し、それほど高速ではありません。私は、関数を使用して、GINインデックスを作成しようとしたnames_as_array(artists)、および使用される'ARTIST NAME' = ANY names_as_array(artists)、しかし、インデックスが使用されず、クエリが大幅に遅くなり、実際にあります。

アーウィンブランドステッター

jsonb Postgres9.4以降

新しいバイナリJSONデータ型jsonbにより、Postgres9.4では大幅に改善されたインデックスオプションが導入されましたjsonb配列に直接GINインデックスを設定できるようになりました。

CREATE TABLE tracks (id serial, artists jsonb);
CREATE INDEX tracks_artists_gin_idx ON tracks USING gin (artists);

配列を変換する関数は必要ありません。これはクエリをサポートします:

SELECT * FROM tracks WHERE artists @> '[{"name": "The Dirty Heads"}]';

@>jsonbGINインデックスを使用できる新しい「contains」演算子です。(タイプjsonではなく、のみjsonb!)

またはjsonb_path_ops、インデックスに、より特殊化されたデフォルト以外のGIN演算子クラスを使用します。

CREATE INDEX tracks_artists_gin_idx ON tracks
USING  gin (artists jsonb_path_ops);

同じクエリ。

現在jsonb_path_ops@>オペレーターのみをサポートしています。しかし、通常ははるかに小さく、高速です。より多くのインデックスオプション、マニュアルの詳細があります


artists例に示されている名前のみを保持している場合は、最初に冗長性の低いJSON値を格納する方が効率的です。テキストプリミティブとしてと冗長キーのみを列名に含めることができます。

JSONオブジェクトとプリミティブ型の違いに注意してください。

CREATE TABLE tracks (id serial, artistnames jsonb);
INSERT INTO tracks  VALUES (2, '["The Dirty Heads", "Louis Richards"]');

CREATE INDEX tracks_artistnames_gin_idx ON tracks USING gin (artistnames);

クエリ:

SELECT * FROM tracks WHERE artistnames ? 'The Dirty Heads';

?オブジェクトは機能せずキー配列要素のみで機能します
または(名前が頻繁に繰り返される場合はより効率的):

CREATE INDEX tracks_artistnames_gin_idx ON tracks
USING  gin (artistnames jsonb_path_ops);

クエリ:

SELECT * FROM tracks WHERE artistnames @> '"The Dirty Heads"'::jsonb;

json Postgres9.3以降

これはIMMUTABLE 関数で動作するはずです

CREATE OR REPLACE FUNCTION json2arr(_j json, _key text)
  RETURNS text[] LANGUAGE sql IMMUTABLE AS
'SELECT ARRAY(SELECT elem->>_key FROM json_array_elements(_j) elem)';

この機能インデックスを作成します

CREATE INDEX tracks_artists_gin_idx ON tracks
USING  gin (json2arr(artists, 'name'));

そして、このようなクエリを使用しますWHEREの式は、インデックスの式と一致する必要があります。

SELECT * FROM tracks
WHERE  '{"The Dirty Heads"}'::text[] <@ (json2arr(artists, 'name'));

コメントのフィードバックで更新されました。GINインデックスをサポートするには、配列演算子を使用する必要があります。オペレータ「に含まれる」このケースでは。
<@

関数のボラティリティに関する注記

IMMUTABLEそうjson_array_elements() でない 場合でも、関数を宣言できます
ほとんどのJSON関数はSTABLE、ではなく、のみでしたIMMUTABLEそれを変えるためにハッカーリストで議論がありました。ほとんどがIMMUTABLE今です。確認する:

SELECT p.proname, p.provolatile
FROM   pg_proc p
JOIN   pg_namespace n ON n.oid = p.pronamespace
WHERE  n.nspname = 'pg_catalog'
AND    p.proname ~~* '%json%';

関数インデックスは関数でのみ機能しますIMMUTABLE

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

空手-JSON応答配列内の要素の複数の出現の配列インデックスを見つけるため

分類Dev

配列内の最小要素のインデックスを見つける(Java)

分類Dev

配列内の最大n個の要素のインデックスを安定した順序で見つける方法

分類Dev

配列要素のインデックスを見つける方法

分類Dev

配列要素のインデックスを見つける

分類Dev

条件を満たす配列要素のインデックスを見つける

分類Dev

配列のインデックスを見つけるためのunordered_map

分類Dev

配列内の最大の負の要素と最小の正の要素のインデックスを見つける

分類Dev

配列内のjsonオブジェクトの現在のインデックスを見つけるための関数はありますか?

分類Dev

C#のラムダ式内の配列内の要素のインデックスを見つける方法

分類Dev

配列内の配列のインデックスを見つける方法

分類Dev

配列内の特定のインデックスの前の最小要素を見つける方法は?

分類Dev

範囲を使用してnumpy配列内のリスト要素のインデックスを見つける方法

分類Dev

別のリストまたは配列に基づいて配列/リスト内の要素のインデックスを見つける

分類Dev

配列内のすべての要素のインデックスを見つける方法は?

分類Dev

Python:配列内の特定の要素のインデックスを見つける方法は?

分類Dev

配列内の最小要素のインデックスを見つけるJavaコードのエラー

分類Dev

Javaで配列内の要素のインデックスを見つける方法は?

分類Dev

2D配列内の要素のインデックスを見つける方法-Swift

分類Dev

配列内の2つの類似した数値のインデックスを見つける方法は?

分類Dev

配列内の最大n値のインデックスを見つける方法

分類Dev

Javascript-配列内の特定のインデックスを見つける

分類Dev

numpy配列で最大要素比較のインデックスを見つける

分類Dev

配列列でインデックスを見つけるためのUDFを作成する方法

分類Dev

特定の要素でソートされた配列の範囲インデックスを見つける

分類Dev

Pythonで配列内のエントリを見つけるためにインデックスを使用する際のエラー

分類Dev

文字列内のインデックスを見つけるための for ループ

分類Dev

別の配列内のある配列の一致のインデックスを見つける

分類Dev

見つけた要素のインデックスを表示する

Related 関連記事

  1. 1

    空手-JSON応答配列内の要素の複数の出現の配列インデックスを見つけるため

  2. 2

    配列内の最小要素のインデックスを見つける(Java)

  3. 3

    配列内の最大n個の要素のインデックスを安定した順序で見つける方法

  4. 4

    配列要素のインデックスを見つける方法

  5. 5

    配列要素のインデックスを見つける

  6. 6

    条件を満たす配列要素のインデックスを見つける

  7. 7

    配列のインデックスを見つけるためのunordered_map

  8. 8

    配列内の最大の負の要素と最小の正の要素のインデックスを見つける

  9. 9

    配列内のjsonオブジェクトの現在のインデックスを見つけるための関数はありますか?

  10. 10

    C#のラムダ式内の配列内の要素のインデックスを見つける方法

  11. 11

    配列内の配列のインデックスを見つける方法

  12. 12

    配列内の特定のインデックスの前の最小要素を見つける方法は?

  13. 13

    範囲を使用してnumpy配列内のリスト要素のインデックスを見つける方法

  14. 14

    別のリストまたは配列に基づいて配列/リスト内の要素のインデックスを見つける

  15. 15

    配列内のすべての要素のインデックスを見つける方法は?

  16. 16

    Python:配列内の特定の要素のインデックスを見つける方法は?

  17. 17

    配列内の最小要素のインデックスを見つけるJavaコードのエラー

  18. 18

    Javaで配列内の要素のインデックスを見つける方法は?

  19. 19

    2D配列内の要素のインデックスを見つける方法-Swift

  20. 20

    配列内の2つの類似した数値のインデックスを見つける方法は?

  21. 21

    配列内の最大n値のインデックスを見つける方法

  22. 22

    Javascript-配列内の特定のインデックスを見つける

  23. 23

    numpy配列で最大要素比較のインデックスを見つける

  24. 24

    配列列でインデックスを見つけるためのUDFを作成する方法

  25. 25

    特定の要素でソートされた配列の範囲インデックスを見つける

  26. 26

    Pythonで配列内のエントリを見つけるためにインデックスを使用する際のエラー

  27. 27

    文字列内のインデックスを見つけるための for ループ

  28. 28

    別の配列内のある配列の一致のインデックスを見つける

  29. 29

    見つけた要素のインデックスを表示する

ホットタグ

アーカイブ