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、または正規表現とのパターンマッチング