2016-11-20 15 views
0

私はPostgreSQL 9.5とJSONBデータ型を使って文書を保管しています。私のテーブルのようなもの:Postgres jsonbで配列内のオブジェクト値を検索するにはどうしたらいいですか?

create table records (
    id serial, 
    data jsonb 
); 

マイドキュメントは、例えばオブジェクトの配列を含む:

{ 
    "some_field": "a value", 
    "another_field": 123, 
    entries: [ 
    { 
     "name": "John Doe", 
     "age": 42 
    }, 
    { 
     "name": "Johnny McMuffin", 
     "age": 117 
    } 
    ] 
} 

問題は、私はentriesname属性でフィルタリングできるようにしたいということですアレイと私はそれを把握することはできません。私は、オブジェクトのリスト内の名前の1つに部分的に一致するテーブル内の行を見つけることができるようにしたい。

私はインデックスや表現などについて多くのことを読んだことがありますが、動作させることはできません。これは可能ではありませんか?

答えて

1

それは期待される結果が何であるか私には不明ですが、このような何かが動作します:

select r.id, e.* 
from records r 
    cross join lateral jsonb_array_elements(r.data -> 'entries') as e 
where e ->> 'name' like '%Doe%'; 

あなたに各配列要素にアクセスできるようにするためには、(それらを「アンネスト」する必要がありますつまり、正規化正規化されていないドキュメント)。上の例では、テーブル内の各行ではなく、一致する配列要素ごとに1つの行が返されることに注意してください。

また、あなたがベーステーブルからの固有の完全な行が必要な場合が存在するサブクエリに名前のチェックを移動することができます:

select r.* 
from records r 
where exists (select 1 
      from jsonb_array_elements(r.data -> 'entries') as e 
      where e ->> 'name' like '%Doe%'); 

を二つの文の違いは、最初のクエリがすること、です一致する配列要素を表示するだけです。 2番目のものは、すべての一致要素の少なくとも1つが文書の配列要素に表示されます。

+0

これはうまくいくようです。私は何らかの形で可能な重複を扱うことができると思います。 – fiskeben

+0

これらは重複していません。これらは配列の複数の値です。しかし、 'exists'クエリを使って基本テーブルから一意の行だけを取得することができます。 –

関連する問題