これはPGroonga 2.X and 3.X用のドキュメントです。古いPGroongaを使っているならPGroonga 1.xのドキュメントを見てください。
LIKE
演算子PGroongaは内部的にcolumn LIKE '%キーワード%'
条件をcolumn %% 'キーワード'
条件に変換します。%%
演算子はインデックスを使って全文検索をします。これはインデックスを使わないLIKE
演算子より速いです。
インデックスを使ったcolumn LIKE '%キーワード%'
はcolumn %% 'キーワード'
よりも遅いです。これは、インデックスを使ったcolumn LIKE '%キーワード%'
は「再検査」する必要があるからです。column %% 'キーワード'
は「再検査」する必要がありません。
元のLIKE
演算子は対象テキストに対して検索します。しかし、%%
演算子は正規化したテキストに対して検索します。そのため、インデックスを使ってLIKE
演算子の検索を実行した場合は「再検査」が必要になります。
ただし、カラムの型が varchar
の場合、 LIKE
または ILIKE
は常にシーケンシャルサーチになります。PGroongaは varchar
に対してインデックスを使えないためです。
この演算子を使うには次のどれかの演算子クラスを指定する必要があります。
pgroonga_text_full_text_search_ops_v2
:text
型のデフォルト
pgroonga_text_regexp_ops_v2
:text
用
pgroonga_text_full_text_search_ops
:text
用
pgroonga_text_regexp_ops
:text
用
この演算子の構文は次の通りです。
column LIKE pattern
column
は検索対象のカラムです。
pattern
は検索パターンです。text
型です。
例に使うサンプルスキーマとデータは次の通りです。
CREATE TABLE memos (
id integer,
content text
);
CREATE INDEX pgroonga_content_index ON memos USING pgroonga (content);
INSERT INTO memos VALUES (1, 'PostgreSQLはリレーショナル・データベース管理システムです。');
INSERT INTO memos VALUES (2, 'Groongaは日本語対応の高速な全文検索エンジンです。');
INSERT INTO memos VALUES (3, 'PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。');
INSERT INTO memos VALUES (4, 'groongaコマンドがあります。');
インデックスを使ってLIKE
演算子を実行できます。
SET enable_seqscan = off;
SET enable_indexscan = on;
SET enable_bitmapscan = on;
SELECT * FROM memos WHERE content LIKE '%groonga%';
-- id | content
-- ----+-----------------------------
-- 4 | groongaコマンドがあります。
-- (1 row)
PGroongaのインデックスが適用しているtext
型用のデフォルトのオペレータークラスは、キーワードがアルファベットのみだった場合、キーワードの一部だけで検索してもヒットしません。たとえば、roonga
というキーワードではヒットしません。
SET enable_seqscan = off;
SET enable_indexscan = on;
SET enable_bitmapscan = on;
SELECT * FROM memos WHERE content LIKE '%roonga%';
-- id | content
-- ----+---------
-- (0 rows)
インデックスを使わない場合はroonga
というキーワードでもヒットします。
SET enable_seqscan = on;
SET enable_indexscan = off;
SET enable_bitmapscan = off;
SELECT * FROM memos WHERE content LIKE '%roonga%';
-- id | content
-- ----+---------------------------------------------------------------------------
-- 2 | Groongaは日本語対応の高速な全文検索エンジンです。
-- 3 | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。
-- 4 | groongaコマンドがあります。
-- (3 rows)
キーワードがアルファベットだけだった場合でも、Gro
のようにキーワードの先頭部分を指定した場合はヒットします。
SET enable_seqscan = off;
SET enable_indexscan = on;
SET enable_bitmapscan = on;
SELECT * FROM memos WHERE content LIKE '%Gro%';
-- id | content
-- ----+---------------------------------------------------------------------------
-- 2 | Groongaは日本語対応の高速な全文検索エンジンです。
-- 3 | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。
-- (2 rows)
キーワードがアルファベットの場合でも、キーワードの一部で検索できるようにする方法は2つあります。
最初の方法はTokenBigramSplitSymbolAlphaDigit
トークナイザーを使う方法です。
DROP INDEX IF EXISTS pgroonga_content_index;
CREATE INDEX pgroonga_content_index
ON memos
USING pgroonga (content)
WITH (tokenizer='TokenBigramSplitSymbolAlphaDigit');
これでroonga
でもヒットするようになります。
SET enable_seqscan = off;
SET enable_indexscan = on;
SET enable_bitmapscan = on;
SELECT * FROM memos WHERE content LIKE '%roonga%';
-- id | content
-- ----+---------------------------------------------------------------------------
-- 2 | Groongaは日本語対応の高速な全文検索エンジンです。
-- 3 | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。
-- 4 | groongaコマンドがあります。
-- (3 rows)
トークナイザーをカスタマイズする方法についてはCREATE INDEX USING pgroonga
のカスタマイズを参照してください。
2つめの方法はpgroonga_text_regexp_ops
オペレータークラスを使う方法です。
DROP INDEX IF EXISTS pgroonga_content_index;
CREATE INDEX pgroonga_content_index
ON memos
USING pgroonga (content pgroonga_text_regexp_ops_v2);
これでroonga
でもヒットするようになります。
SET enable_seqscan = off;
SET enable_indexscan = on;
SET enable_bitmapscan = on;
SELECT * FROM memos WHERE content LIKE '%roonga%';
-- id | content
-- ----+---------------------------------------------------------------------------
-- 2 | Groongaは日本語対応の高速な全文検索エンジンです。
-- 3 | PGroongaはインデックスとしてGroongaを使うためのPostgreSQLの拡張機能です。
-- 4 | groongaコマンドがあります。
-- (3 rows)