「とりあえず `to_tsvector(‘english’, column)` で検索してるんだけど、なんか精度がイマイチなんだよね……」
もしあなたが今、PostgreSQLの全文検索でそんな壁にぶつかっているなら、この記事はまさにその悩みに対する特効薬になるはずです。
PostgreSQLの全文検索って、実は非常に奥が深いんです。単なる「文字列マッチング」ではなく、「言語ごとの文法や文脈を理解させる」というフェーズを挟むだけで、検索体験は劇的に向上します。その要となるのが、今回解説する「全文検索設定(Text Search Configuration)」です。
—
全文検索設定(Configuration)って何者?
簡単に言うと、「そのテキストをどうやってバラバラにして(トークナイズ)、どうやって正規化して、どうやってインデックスに乗せるか」というルールブックのことです。
`to_tsvector` を呼ぶときに言語を指定しますよね。あれは実は、内部で特定の「設定」を呼び出しているんです。設定の中身は大きく分けて以下の3つで構成されています。
1. パーサー(Parser): テキストを単語や記号に分解する。「これはメールアドレス、これは単語、これは数値」といった分類をしてくれます。
2. 辞書(Dictionary): 分解された単語をどう扱うか。ストップワード(the, a, and など)を除外したり、単語の語幹(stemming)を揃えたりします。
3. マッピング: パーサーが分類したトークンに対して、どの辞書を適用するかを定義します。
実践:日本語の検索を「ちょっとマシ」にする
PostgreSQL標準の `japanese` 設定も悪くないんですが、実務では「もう少し柔軟にやりたい」というケースがほとんどです。
例えば、「特定の単語を除外したい」「同義語を統合したい」といったケース。これらには「カスタム設定」を作るのが一番の近道です。
1. 辞書を作成する
まず、独自のルールを持つ辞書を作ります。今回は、不要な記号や特定の社内用語を無視する設定を想定しましょう。
— カスタムストップワード辞書を作る(ファイルパスを指定)
CREATE TEXT SEARCH DICTIONARY my_stop_words (
TEMPLATE = pg_catalog.simple,
STOPWORDS = my_stop_words_file — 独自のテキストファイルを指定
);
2. 設定(Configuration)を定義する
次に、デフォルトの日本語設定をコピーして、自分好みにカスタマイズします。
— pg_catalog.japanese をベースに作成
CREATE TEXT SEARCH CONFIGURATION public.my_custom_config (COPY = pg_catalog.japanese);
— 単語の分類(token type)に対して辞書を割り当てる
ALTER TEXT SEARCH CONFIGURATION public.my_custom_config
ALTER MAPPING FOR asciiword, word WITH my_stop_words, simple;
こうすることで、検索エンジンに「この単語は無視してくれ」「この単語は原形に戻さずそのまま扱ってくれ」と指示が出せるようになるわけです。
実務で意識すべき「インデックス」との関係
ここからが先輩エンジニアからのアドバイスです。
設定をカスタマイズしたら、必ずGINインデックスを作成するはずですが、ここで一つ注意点。インデックスを作る時の設定と、検索する時の設定(Configuration)は必ず一致させてください。
— インデックス作成時
CREATE INDEX idx_text_search ON my_table
USING GIN (to_tsvector(‘public.my_custom_config’, content));
— 検索時
SELECT FROM my_table
WHERE to_tsvector(‘public.my_custom_config’, content) @@ to_tsquery(‘public.my_custom_config’, ‘検索キーワード’);
ここがズレていると、インデックスが全く効かず、フルスキャンが走ってパフォーマンスが死にます。初心者がやりがちなミスなので、ここはメモっておいてくださいね。
最後に:完璧を求めすぎないことも大切
正直に言うと、PostgreSQLの標準機能だけで「Googleみたいな検索」を目指すと、どこかで限界が来ます。特に日本語の形態素解析(KuromojiやMeCabなど)を細かく制御したいなら、`pg_bigm` を使ったり、最終的には Elasticsearch や OpenSearch に逃げるという判断も、優れたエンジニアの「引き出し」の一つです。
ただ、小規模〜中規模のプロジェクトであれば、今回紹介した Configuration を適切にチューニングするだけで、ユーザー満足度は驚くほど変わります。
まずは `\dF` コマンドで、今どんな設定が使えるのか覗いてみるところから始めてみてください。データベースの中身が「単なる文字の羅列」から「意味のある情報」に変わる瞬間が見えるはずですよ。
それでは、また現場で会いましょう!
コメント