sql >> データベース >  >> RDS >> PostgreSQL

フラットjsonb配列の要素に対するLIKEクエリ

    SELECT *
    FROM   posts p
    WHERE  EXISTS (
       SELECT FROM jsonb_array_elements_text(p.tags) tag
       WHERE  tag LIKE '%TAG%'
       );
    

    関連、説明付き:

    • JSON配列でパターンに一致する値を含むオブジェクトを検索します

    または、 @?を使用すると簡単になります Postgres12がSQL/JSONを実装してからの演算子:

    SELECT *
    --     optional to show the matching item:
    --   , jsonb_path_query_first(tags, '$[*] ? (@ like_regex "^ tag" flag "i")')
    FROM   posts
    WHERE  tags @? '$[*] ? (@ like_regex "TAG")';
    

    演算子@? 関数jsonb_path_exists()の単なるラッパーです 。したがって、これは同等です:

    ...
    WHERE  jsonb_path_exists(tags, '$[*] ? (@ like_regex "TAG")');
    

    どちらもインデックスをサポートしていません。 (@?に追加される場合があります 後で演算子が表示されますが、13ページにはまだありません)。したがって、これらのクエリは大きなテーブルでは低速です。すでに提案されているローレンツのような正規化された設計の方が優れています-トリグラムインデックスを使用:

    • PostgreSQLLIKEクエリのパフォーマンスのバリエーション

    プレフィックスマッチングの場合 (LIKE 'TAG%' 、先頭のワイルドカードはありません)、フルテキストインデックスで機能させることができます :

    CREATE INDEX posts_tags_fts_gin_idx ON posts USING GIN (to_tsvector('simple', tags));
    

    そして一致するクエリ:

    SELECT *
    FROM   posts p
    WHERE  to_tsvector('simple', tags)  @@ 'TAG:*'::tsquery
    

    または、englishを使用します simpleの代わりに辞書 (またはあなたのケースに合うものなら何でも)あなたが自然な英語のためにステミングしたいなら。

    to_tsvector(json(b)) Postgres 10が必要です またはそれ以降。

    関連:

    • GINインデックス付きTSVECTOR列から部分一致を取得
    • PostgreSQLのLIKE、SIMILAR TO、または正規表現とのパターンマッチング



    1. PostgreSQL 8.4は、すべてのテーブルに対するDML特権をロールに付与します

    2. MySQLテーブルにカスタムCHECK制約を追加するにはどうすればよいですか?

    3. GI12.2アップグレード用にASMのVOTEディスクグループを増やす

    4. インクリメンタルデータのマスキングとマッピング:変更の検出と更新…