BloGroonga

2023-04-13

PostgreSQL用高速日本語全文検索モジュールPGroonga(ぴーじーるんが) 3.0.0リリース

PostgreSQLで高速日本語全文検索をできるようにするPGroongaの3.0.0をリリースしました!メジャーバージョンアップです!

PGroongaについて

メジャーバージョンアップのリリースアナウンスなので、PGroongaについての説明をします。今回の変更のハイライトはこの後にまとめています。

PGroongaはPostgreSQLを高速に日本語全文検索可能なシステムに拡張する魔法のような拡張機能です。PGroongaの他にも類似の拡張機能はありますが、速度・機能面で他の拡張機能とは一線を画しています。これはPGroongaはバックエンドにGroongaという本格的な全文検索エンジンを使っているためです。

性能

性能面では類似の拡張機能であるpg_bigmよりも高速です。PostgreSQL本体に含まれている全文検索モジュールtextsearchよりも高速です。インデックス作成時間、検索時間ともに数倍から10倍以上高速です。

まずはPGroongaとpg_bigmのインデックス作成時間です。Wikipedia日本語版データを使っています。

拡張機能 インデックス作成時間
PGroonga 約19分
pg_bigm 約33分

このケースでは2倍弱高速です。

続いてPGroongaとtextsearchのインデックス作成時間は次の通りです。textsearchが日本語非対応なのでWikipedia英語版データを使っています。データ量が違うので↑の結果とは直接比較はできません。

拡張機能 インデックス作成時間
PGroonga 約1時間24分
textsearch 約2時間53分

このケースでは2倍強高速です。

PGroongaとpg_bigmの検索時間は次の通りです。

検索語 ヒット数 PGroongaの検索時間 pg_bigmの検索時間
「PostgreSQL」または「MySQL」 約300 約2ms 約49ms
データベース 約1万5千 約49ms 約1300ms
テレビアニメ 約2万 約65ms 約2800ms
日本 約53万 約560ms 約480ms

「日本」で検索した場合はpg_bigmの方がやや速い(*1)ですがそれ以外の場合ではPGroongaの方が24倍から43倍ほど高速です。どのような検索語に対しても安定して高い性能を出していると言えます。

(*1) pg_bigmは3文字以上の検索語より2文字以下の検索語の方が得意です。

PGroongaとtextsearchの検索時間は次の通りです。

検索語 ヒット数 PGroongaの検索時間 textsearchの検索時間 Groongaの検索時間
「PostgreSQL」または「MySQL」 約1600 約6ms 約3ms 約3ms
database 約21万 約698ms 約602ms 約19ms
animation 約4万 約173ms 約1000ms(*2) 約6ms
America 約47万 約1300ms 約1200ms 約45ms

(*2) textsearchでは「animation」で約42万件(PGroongaの約10倍)ヒットしているため遅いです。要因は「animation」を「anim」とステミングしているからです。

PGroongaとtextsearchの検索時間はほぼ同じです。「animation」でtextsearchの方が遅いのはヒット数の違いからくるもので、本質的な検索速度の差ではありません。

参考までにPGroongaが使っている全文検索エンジンGroongaでの結果もつけています。Groongaではすべて数十msで検索できているので、PGroonga・textsearchの検索速度は、全文検索の速度ではなくPostgreSQL内の共通のオーバーヘッドの影響が大きいということがわかります。

ベンチマークの詳細は以下を参照してください。

機能

機能面では次の機能を提供しています。他の類似拡張機能にはない機能も含まれています。

  • ノーマライズ機能
  • トークナイザーのカスタマイズ機能
  • トークンフィルターのカスタマイズ機能
  • クエリー言語を用いた検索
  • HTML対応のハイライト機能
  • HTML対応のスニペット機能
  • JSON検索
  • オートコンプリート機能
  • 類似文書検索機能
  • 同義語展開機能
  • 重み付け指定機能

ノーマライズ機能とは異なる表記のテキストを同等の表記のテキストに統一する処理です。

簡単なものでは「ポスグレ」というようにいわゆる半角カタカナで書かれたテキストも「ポスグレ」もどちらも「ポスグレ」というようにいわゆる全角カタカナに統一します。こうすることにより「ポスグレ」(全角カタカナ)で検索しても「ポスグレ」(半角カタカナ)で書かれたテキストでもヒットするようになります。

難しいものだと「㍊」は「ミリバール」に変換します。これらはUnicodeのNFKCという方法をベースにしています。

トークナイザーのカスタマイズ機能とは検索キーワードとなるキーワードを抽出する処理(トークナイズ処理)をカスタマイズできる機能です。抽出処理をカスタマイズすることにより、検索精度・検索性能のトレードオフをユーザーがコントロールできるようになります。

たとえば、「形態素解析器を使ったトークナイザー」というものにすれば精度・性能は向上しますが、検索漏れが発生することがあります。なお、他の類似拡張機能で形態素解析器を使ったトークナイズ処理をできるものはありません。PGroongaだけです。

トークンフィルターのカスタマイズ機能とはトークナイザーで抽出したキーワードを加工する処理をカスタマイズできる機能です。textsearchではdictionaryという名前で同様の機能があります。PGroongaもtextsearchもステミング機能はこの仕組みで実現しています。

クエリー言語を用いた検索とは「A OR (B -C)」というようにAND/OR/NOT検索をユーザーが指定できる機能です。Googleと同様の文法で使えます。

HTML対応のハイライト機能とは検索キーワードを<span class="keyword">...</span>でマークアップする機能です。結果はそのままHTML内で使っても安全です。Webアプリケーションの開発に便利です。

HTML対応のスニペット機能とは検索キーワード周辺テキストを返す機能で、Googleの検索結果でも使われています。もちろん、キーワードは<span class="keyword">...</span>でマークアップされます。こちらも結果をそのままHTML内で使っても安全です。

JSON検索機能とはjsonb型のカラム全体をインデックスに登録し、柔軟に検索できる機能です。JSON内のすべてのテキストを全文検索することもできるため、JSON形式でいろんな構造のログを保存しておいて後で検索、といったことも簡単にできます。

オートコンプリート機能とは検索キーワードを入力するテキストボックスで入力キーワードを補完する機能です。Googleでも実装されている機能です。Googleと同様にローマ字で入力しても補完できます。

類似文書検索機能とは内容が似ているテキストを検索する機能です。ブログで類似記事を表示するために使えます。

同義語展開機能とは同じ意味だけど表現の違うキーワードをまとめて検索する機能です。たとえば「牛乳」と検索したときに「牛乳」も「ミルク」も検索します。

重み付け指定機能とはスコアーを調整する機能です。この機能によりより重要なレコードをファーストビューで表示することができます。たとえば、「タイトル」カラムと「本文」カラムがあり、「タイトル」カラムの内容の方が重要だとします。この場合、指定されたクエリーが「タイトル」カラムの内容にヒットしたらスコアーを+10する、「本文」カラムの内容にヒットしたらスコアーを+1するということができます。この調整とソートを使うことで、結果セットの最初の方に重要なレコードを集めることができます。

それぞれの機能が気になった人はPostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システムや、リファレンスマニュアルハウツードキュメントも見てください。

使い方

PGroongaは全文検索のことをあまり知らなくても簡単に使えます。インデックスを作成してWHEREに条件を指定するだけです。

CREATE INDEX index_name ON table USING pgroonga (column);

SELECT * FROM table WHERE column &@~ '全文検索';

LIKEでもインデックスを使って検索できる機能を提供しているため、既存アプリケーションで次のように書いていたとしてもアプリケーションを変更せずに高速にできます。ただし、LIKEの方が全文検索専用の演算子&@~よりも遅いので、おいおいは専用の書き方に直していくことをオススメします。

SELECT * FROM table WHERE column LIKE '%全文検索%';

興味がでてきましたか?インストールしてチュートリアルを試してみてください。一通りの機能を確認できます。

インストールは簡単です。主要なプラットフォーム用にパッケージを提供しているからです。Windows用のバイナリーも提供しています。

ハイライト

今回のリリースの紹介に戻ります。

PGroonga 3.0.0には非互換な変更があります。しかし、Supabaseのユーザーを含む多くのPGroongaユーザーには影響がありません。そのため、いつもどおりPGroonga 3.0.0にアップグレードできます。

ALTER EXTENSION pgroonga UPDATE;

もし、PGroonga 1.Y.Zユーザーの場合は、PGroonga 3.0.0には非互換な変更があります。pgroongaスキーマを使うのをやめてPGroonga 2.0.0から導入された新しいpgroonga_*関数・演算子など使う必要があります。pgroonga_*関数・演算子などはPGroongaをインストールしたスキーマにあります。

2.4.7以降のハイライトは次の通りです。

  • pgroonga_query_extract_keywords()でインデックスオプション「query_allow_column=true」を使えるようになりました。pgroonga_query_extract_keywords()にインデックスオプション「query_allow_column=true」を使っているインデックスの名前を渡せば使えます。

  • text[]カラムとvarchar[]カラムの単語検索でクエリー言語を使えるようになりました。詳細は&=?演算子を読んでください。

アップグレード方法

2.0.0以降を使っている場合はアップグレードの「互換性がある場合」用の手順でアップグレードしてください。

1.Y.Zを使っている場合はアップグレードの「非互換の場合」用の手順でアップグレードしてください。

サポートサービス

PGroongaのサポートサービスを提供しています。インデックスや検索の設計方法に関するコンサルティングやトラブル時の調査、パフォーマンス改善・新機能追加などの技術支援など、PGroongaに関わるサポートが必要な場合はご相談ください。

まとめ

PGroongaの新しいリリースを紹介しました。PGroonga 3はよりPostgreSQLらしく使えるようになっています。

PostgreSQLで高速に日本語全文検索をしたいという方はPGroongaを使ってガンガン検索してください!