BloGroonga

2017-10-10

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

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

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だけです。

「形態素解析器を使ったトークナイザー」にはMeCab(OSS)を使ったものとJMAT(非OSSの商用製品)を使ったものがあります。バックエンドで使っているGroongaはトークナイザーをプラグインとして追加できる機能を提供しているため様々なプロダクトを活用してトークナイザーを実装できるのです。

トークンフィルターのカスタマイズ機能とはトークナイザーで抽出したキーワードを加工する処理をカスタマイズできる機能です。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と同様にローマ字で入力しても補完できます。

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

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

それぞれの機能が気になった人はPostgreSQLとPGroongaで作るPHPマニュアル高速全文検索システムも見てください。

現在は未実装ですが、今後、提供予定の機能には次のような機能があります。これらはGroongaでは実装されている機能です。

  • 重み付け指定機能

使い方

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用のバイナリーも提供しています。

ハイライト

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

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

  • PostgreSQL 10のサポート

  • クエリーの実行プランの精度向上(高速化)

  • pgroongaスキーマの非推奨化

    • PGroonga 1系と後方互換性を維持しているため、従来通りpgroongaスキーマを使うこともできます。

それぞれ説明します。

PostgreSQL 10のサポート

先日リリースされたPostgreSQL 10に対応しています。最新のPostgreSQLでPGroongaを使えます!

PostgreSQL 10から導入されたロジカルレプリケーションにも対応しています。従来のフィジカルレプリケーションでもレプリケーションできましたが、PostgreSQL 10対応で新しい選択肢が増えたことになります。用途にあわせて使い分けてください。

従来のフィジカルレプリケーションを使うとディスク使用量が多いのですが、ある程度クラッシュリカバリーが効くようになります。

一方、ロジカルレプリケーションではより柔軟なスキーマ構成を実現できます。たとえば、マスターは更新専用にし、参照はスレーブだけで受付、PGroongaのインデックスはスレーブだけに作る(マスターには作らない)という構成もできます。こうすることで、更新性能を向上させつつ、参照に対してスケールアウトする構成にできます。

それぞれのレプリケーション方法についてベンチマークを実施する予定です。結果を楽しみにしていてください。

PostgreSQLクラスターの構成について商用サポートが必要な場合はPGroongaのサポートページを参照してください。

クエリーの実行プランの精度向上(高速化)

PostgreSQLのプランナーはPGroongaを含む各インデックスから情報を取得して処理コストを計算し、最適な実行プランを選択します。PGroongaがより精度の高い結果をプランナーに返せば、より高速な実行プランを選択できるようになります。

今回のリリースではSTABLEな関数(DBの内容によらず引数が同じなら結果が同じになる関数)・IMMUTABLEな関数(同一トランザクション内で引数が同じなら結果が同じになる関数)の結果を使って検索するときの実行プランの精度が向上しました。PGroongaで使うIMMUTABLEな関数の代表はpgroonga_query_expand()です。これはクエリー展開をする関数で、次のように検索クエリーに対して使います。このように検索クエリーを加工する関数を使ったときでもより高速な実行プランを選択しやすくなりました。

SELECT *
  FROM diaries
 WHERE content &@~ pgroonga_query_expand('synonyms', 'term', 'synonyms',
                                         'ユーザーが入力した検索クエリー');

pgroongaスキーマの非推奨化

PGroonga 1系ではpgroongaスキーマ以下に関数やオペレータークラスを定義していましたが、カレントスキーマ(多くの場合はpublic)以下にプレフィックス付きで定義した方が使いやすいという声が多かったです。そのため、PGroonga 2系ではpgroongaスキーマを非推奨とし、pgroonga_プレフィックス付きの名前で定義するようにしました。

pgroongaスキーマは非推奨となりましたが、後方互換性を維持するために従来通りpgroongaスキーマを使うこともできます。安心してアップグレードしてください。少なくともPGroonga 2系の間はpgroongaスキーマをサポートするので、徐々にpgroonga_プレフィックスを使った使い方に更新していってください。

アップグレード方法

1.0以降のすべてのバージョンと互換性があります。アップグレードの「互換性がある場合」用の手順でアップグレードしてください。

おしらせ

セッション

2017年11月3日(金、祝日)にPostgreSQL Conference Japan 2017PGroonga 2.0 - PostgreSQLでの全文検索の決定版というセッションがあります。

2017年12月5日(金)にPGConf.ASIA 2017PGroonga 2.0 – Make PostgreSQL rich full text search system backend!というセッションがあります。

どちらもPGroonga 2関連のセッションですが、PostgreSQL Conference Japan 2017の方がまだPGroongaを使っていない人向け、PGConf.ASIA 2017の方がPGroongaをすでに使っている人と拡張機能を開発している人向けの内容になります。

サポートサービス

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

まとめ

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

ここで紹介したもの以外の変更点はリリースノートを参照してください。

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