2016-10-22 3 views
1

data_filtersという名前のjsonbカラムのキー['kommune'、 'fylke'、 'år']を含む行の後ろを照会しようとしています。PostgreSQL(正確にこれらのキー)で正確なjsonキーが一致するかどうかの問い合わせ

私が見ることができる限り、このオペレータは?&しか持っていませんが、私はこれらすべてのキーを持つすべての行を与えていますが、(例えば)キー '趣味'を持つ行は望ましくありません。これまでのところ、私はこの使用しています:

select * from main_dataitem 
where array['fylke', 'kommune', 'år'] @> ARRAY(select jsonb_object_keys(data_filters)) 
and ARRAY(select jsonb_object_keys(data_filters)) @> array['fylke', 'kommune', 'år']; 

をしかし、これは、いずれかがこれを照会するためのより良い方法を持って、最適な解決策のように見えるしていませんか?

select * from main_dataitem where data_filters ?& array['fylke', 'kommune', 'år']; 
+1

配列を取得するには、 'array(xによってjsonb_object_keys(data_filters)からxを選択)'を使い、 '='だけを使って順序付き定数配列と比較します。 – Abelisto

+0

私は両方の配列をソートしなければならないでしょうか?また、これは高速ですか? –

+0

1)はい、両方の配列をソートする必要があります( 'array [1,2]!= array [2,1]')2)試してみてください。 IMOは速くなければなりませんが、私はJSONとして構造化されたデータを格納するというファンではありませんので、私はそれをあまり使い慣れていません。 – Abelisto

答えて

0

おそらくそれは次のようになります。

はちょうどそれが(私は指定していないこと)指定されたキーとプラス任意のキーを含む行に一致するため、これは望ましい結果が得られていない、明確されるように(純粋なCの機能を除く)最速:もちろん

create or replace function jsonb_same_keys(p_json jsonb, p_keys text[]) 
returns boolean immutable strict language plpythonu as $$ 
    import json 
    j = json.loads(p_json).keys() 
    return sorted(j) == sorted(p_keys) 
$$; 

select jsonb_same_keys('{"1":2,"2":1}'::jsonb, array['2','1']); 
╔═════════════════╗ 
║ jsonb_same_keys ║ 
╠═════════════════╣ 
║ t    ║ 
╚═════════════════╝ 

あなたはPythonがインストールされている必要があり、PostgreSQLの言語拡張:create extension plpythonu;

0

これがまだ関連しているかどうかはわかりません(これは> 1年前に尋ねられたものですが)、最近この問題を偶然見つけました。

jsonbを使用している場合は、-演算子を使用することもできます。これにより、JSON値から1つ以上のキーセットが削除されます。指定されたキーを持つオブジェクトのみを照会する場合、この操作の結果は空のJSON({})である必要があります。

ので、クエリは次のようになります。

(ちょうど完全性について)Abelistoの答え@に関連
select * from main_dataitem where (data_filters - array['fylke', 'kommune', 'år']) = '{}'; 

、あなたはまた、JSONのキーの抽出を行い、jsonb_object_keys/json_object_keys機能を使用してソートすることができます。このような何か:

select * from main_dataitem where array(select x from jsonb_object_keys(data_filters) as x order by x) = array['fylke', 'kommune', 'år']; 

私自身のテストデータセット(〜330K行)で、私は、これは私も上記の提案最初の選択肢よりも大幅に遅くなることが判明しました。

また、私はPostgreSQL 10.0でこれを行いました。

関連する問題