2017-10-11 9 views
1

キーバリュー文書を保管するためにPostgresにjsonbタイプを使用します。また、これらのドキュメントの上にGINインデックスを使用して、高速検索を行います。デフォルトでは、GINインデックスは冗長である傾向があります。つまり、jsonb構造内のすべてのキーをインデックスします。私はより選択的なインデックス作成をしたいと思います。Postgresのjsonbデータで選択キーをインデックスする方法は?

GINインデックスでこれを行うことはできますか?

  1. GINはトップレベルのキーのみをインデックスし、ネストされた構造はインデックスを解除したままにしますか? OR
  2. はGINインデックスのみ特定のキーワード(私はそれがGINを経由して成し遂げることができれば、私は知ることに興味がある。私はインデックスを作成する必要がキーワードごとに別々のBTREEインデックスを作成することができることを承知している)
を持っています

ありがとうございます。

答えて

1

あなたがしてGINとインデックスができることを、キーの入力や配列としてJSONBドキュメントを取り、そして濾過キーで新しい文書を返す補助関数を使用して行うことができます。

create function jsonb_filter(doc jsonb, variadic keys text[]) 
returns jsonb 
as 'select jsonb_object_agg(key, doc->key) from unnest(keys) key' 
language sql 
immutable; 

create index filtered_index on jsonb_table 
using gin (jsonb_filter(data, 'a', 'b')); 

select data->'a' 
from jsonb_table 
where jsonb_filter(data, 'a', 'b') @> '{"a":1}'; 

あなたがしたいことクエリ内で繰り返されないように、関数内でフィルタリングするキーのセットをハードコーディングします。

あなただけのインデックスいくつかのキーの存在したい場合は、:

create function jsonb_keys(doc jsonb) 
returns text[] 
as 'select array_agg(key) from jsonb_object_keys(doc) key' 
language sql 
immutable; 

create index keys_index on jsonb_table 
using gin (jsonb_keys(data)); 

select data->'b' 
FROM jsonb_table 
where jsonb_keys(data) @> ARRAY['a']; 

機能jsonb_keysは、インデックスを作成するキーのみを含むように変更することができます。

ここに関連するSqlFiddleがありますhttp://sqlfiddle.com/#!17/b7935/6

+0

さらに多くのデータをフィディルドに追加しますか?それで、yoiurインデックスを使用し始めますか?それ以外の場合はデモが動作しません:) –

+0

@ VaoTsun有効なポイントですが、インデックスを適格にするためのキーは、クエリフィルタで_indexed式_を使用することです:) – Tair

関連する問題