MySQL用N-Gram全文検索プラグイン

 

[English]

単純なMySQL(5.1+)用、N-Gram (bi-gram) 全文検索プラグイン

 

注:現在、この全文検索プラグインより少し高度な物を作られている方がいらっしゃるようです。「MySQL full-text parser plugin collection」 より現実的な運用にはそちらや、sennaをMySQLへ組み込んだ「Tritonn」の方が良いかもしれません。

 

MySQL には全文検索機能がありますが、これは単語単位のインデックスを作るので、日本語や中国語のような単語の切れ目が簡単にわからない言語には使用することが できません。それに、単語の真ん中にある文字で検索してもヒットしません。 (例:検索語 'in' は 'ping' にマッチしない。)

MySQL 5.1からMySQLにはプラグインがサポートされ、サーバーを再起動したり再コンパイルすることなくサーバーの機能の一部(全文検索パーサー)を入れ替えることができるようになりました。

このパーサーはこのプラグインの機能を使って、ごく単純なN-gram (bi-gram) 全文検索パーサーを実現した物です。senna のような高精度の検索は出来ませんが、簡単にインストールして試してみることが出来ます。

N-gramパーサ

N-gram (bi-gram) は簡単なアルゴリズムで、テキストから2つの連続した文字を取り出してインデックスを作ってゆきます。このプラグインではMySQLの内部マルチバイト関 数を使って2つの連続した文字を取り出しているので、MySQLがサポートするSJIS/UJIS/UTF-8などの、すべてのエンコーディングで使用す ることが出来ます。

プラグイン自身も非常に簡単で、MySQLのソースコードに付属している全文検索パーサのサンプルコードから、基本的には1つの関数(bi_gram_parser_parse, in bi_gram_plugin.c)を変更しただけで出来上がっています。

ヴァージョン1.0.1

 * 足りないファイルを追加。 (ChangeLog, COPYING, etc.)
 * ライセンスを GPL から LGPL へ変更。
 * Fixed: ./configure のパラメータをちゃんと使うようにした。
 * Fixed bug: 検索/インデックス時に1文字だけ入力された場合の不具合を修正。

コンパイル

1) ソースコードをダウンロードしてください: bi_gram-src-1.0.1.tar.gz .

2) ./configure --prefix=/usr (or /usr/local)

3) make(MySQLヘッダーがインストールされている必要があります。)

4) make install (プラグインは上の--prefixの下、/usr/lib/mysql/ などにインストールされます。)

 (注)最近のヴァージョンのMySQLソースでは、「In_C_you_should_use_my_bool_instead」と言うエラーが出る場合がありますが、この時にはエラー箇所のboolをmy_boolに変えてください。

(注2)i386マシンを使っている場合には、プリコンパイルしたバイナリ bi_gramlib.so をダウンロードして、/usr/lib/mysql等にコピーしてもかまいません。

インストール

1) 上の「コンパイル」の4)の項のようにmake install、あるいはダウンロードした bi_gramlib.so を/usr/lib/mysql等へコピーしてください。

2) /etc/my.cnf に以下の行を追加します。

[mysqld]
ft_min_word_len=1

3) MySQLサーバーをリスタートします。(my.cnfの変更を有効にするため)

4) サーバーに 'mysql' コマンドで接続し、以下のコマンドを実行します。

INSTALL PLUGIN bi_gram SONAME 'bi_gramlib.so';

('SHOW PLUGINS'でチェックできます)


使用法

1) 「WITH PARSER bi_gram」を指定して、全文インデックスを作ります。

 ('create table' or 'create index'等).

CREATE TABLE t (c VARCHAR(255), FULLTEXT (c) WITH PARSER bi_gram);

もしくは、、、

CREATE FULLTEXT INDEX c ON t(c) WITH PARSER bi_gram;

2) 'match - against' 構文を使って全文検索を行います。

SELECT MATCH(c) AGAINST('case' IN BOOLEAN MODE) FROM t;

Note: IN BOOLEAN MODE以外では使えません。

 

既知のバグ

語末に改行がある場合の単語の検索が上手く行かないようです。(このbi-gramパーサー自身は改行を単に区切りとして単語を切り出しているのですが、どうもMySQL内部で行末等に特別な処理があるのか、検索がされないようです。ちょっと時間がかかりそうですが、原因を調べています。)

リンク