トップ > 製品・サービス > MySQL > 全文検索ソリューション
MySQL
MySQL / senna

MySQL+Sennaによる日本語全文検索ソリューション


 

1.全文検索とは

 

全文検索とは特定のキーワードを含むテキストを、インデックスを使用して検索することです。RDBMSにおいて一般的に使用されるBtreeインデックスは、ID、名前、商品名、日付といった主にデータ長の短いカラムにおいて使用されますが、全文検索に使用するFULLTEXTインデックスは商品の説明文、Eメールの本文といった長いテキストを格納しているカラムに対して使用されます。

長いテキストを格納しているテーブルから特定のキーワードを含むテキストを検索するには、通常の検索と同様に以下のようなSQL文を実行することで、検索することも可能です。

SELECTcolumnFROMtableWHEREcolumnLIKE‘%key_word%’;

しかしながら、このような部分一致検索の場合には、インデックスを使用した検索ができず、検索速度が遅くなってしまいます。百科事典を巻末の索引を使用せずに、1ページ目から順番に読んでいくようなものです。

一方、以下のようなSQL文を実行する全文検索においては、FULLTEXTインデックスを使用した検索ができる為、非常に高速です。

SELECTcolumnFROMtableWHEREMATCH(column)AGAINST(‘hoge’);


  ▲ページ上部へ▲
 

2.MySQLにおける全文検索の問題点

 

現在、MySQLには日本語環境で使用するための十分な全文検索機能が実装されていません。

例えば英語の場合、以下のように全文検索をすることができますが

[test]>SETNAMESutf8;
QueryOK,0rowsaffected(0.00sec)

[test]>CREATETABLEt1(c1TEXT,FULLTEXT
ULTCHARSETutf8;
QueryOK,0rowsaffected(0.00sec)

[test]>INSERTINTOt1VALUES("Ihaveapen."),("MayIHelpYou?"),("Haveaniceday.");
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0
[test] > SELECT * FROM t1 WHERE MATCH(c1) AGAINST("nice");
+------------------+
| c1        |
+------------------+
| Have a nice day. |
+------------------+
1 row in set (0.00 sec)

日本語の場合、結果が0 件になってしまいます。

[test] > drop table t1;
Query OK, 0 rows affected (0.00 sec)

[test] > CREATE TABLE t1 (c1 TEXT, FULLTEXT INDEX idx (c1)) ENGINE = MyISAM DEFAULT CHARSET utf8;
Query OK, 0 rows affected (0.00 sec)

[test] > INSERT INTO t1 VALUES("私はペンを持っています。"), ("いらっしゃいませ〜"), ("良い一日を。");
Query OK, 3 rows affected (0.00 sec)
Records: 3 Duplicates: 0 Warnings: 0

[test] > SELECT * FROM t1 WHERE MATCH(c1) AGAINST("良い");
Empty set (0.00 sec)

なぜこのようなことが起きるかというと、これはMySQLの全文検索(FULLTEXT)インデックスのキーワード抽出を行うパーサが「半角スペースで区切られているものをキーワードとして認識する」という実装になっているためです。欧米の言語は通常、単語と単語の間は半角スペースで区切られていますので機能しますが、日本語の場合はそうではないためキーワードの抽出を行えません。

例えば、「私はペンを持っています。」を例にすると、あらかじめ「私は ペンを 持って いま す。」のように半角スペースで区切っておけば(分かち書きと言います)現在のMySQLでも日本語全文検索を行うことができます。しかしMySQLに入力するデータをあらかじめ分かち書きするのは、その分処理が増えるのでできれば避けたいですし、オリジナルのデータと別に分かち書きしたデータを用意しなければならないのは効率が良くありません。

  ▲ページ上部へ▲
 

3. MySQL+Senna による日本語全文検索

 

このような問題点はMySQL+Sennaの組み合わせで、解決することができます。
Sennaとはオープンソースの全文検索エンジンです。Sennaを使用することで、全文検索インデックスのキーワード抽出にあたって、形態素解析(mecabを使用)やn-gramといった手法が使用できる為、MySQLにおいても日本語のテキストに対して有効なインデックスを作成することが可能となります。

加えて、Sennaは以下の様な特徴を持っています。

  • 組込み型
    MySQLに組み込んで使用する為、MySQLがアプリケーションからSennaを隠蔽します。開発者の方はSQL文を操作するだけで、全文検索を実行できます。
  • 高速
    キーワードがテキスト内のどの位置にあるかという位置情報を持った、完全転置インデックスを採用している為、フレーズ検索においても高速な検索が可能です。
  • 即時検索
    作成したインデックスに対して、インクリメンタルに文書の追加/変更/削除の操作を加えることができるため、文書に次々と変更が加えられる場合にも、一度作成したインデックスを作成し直す必要がありません。

MySQLにSennaを組み込むには、MySQLのソースコードにパッチをあて、修正を加える必要があります。これにより、FULLTEXTインデックスの処理にMyISAMのビルトインのFULLTEXTインデックスではなく、Sennaを使うようになります。MySQLにSennaを組み込んだ場合のSennaの位置づけは以下の図の様なイメージとなります。

  ▲ページ上部へ▲
 

4. Tritonn プロジェクト

 

Tritonn とは、MySQLに全文検索エンジンのSennaを組み込むためのパッチ(以下、MySQL バインディングパッチ)を開発する、オープンソースプロジェクトです。従来MySQL バインディングパッチは、Senna プロジェクトによって提供され てきましたが、2007年3月よりSennaのサブプロジェクト"Tritonn"として独立して開発、管理されています。また、MySQL+Sennaを実現するTritonnの使用方法についても詳しく解説されています。

  MySQL+Sennaのサポートサービスはこちら
MySQL詳細情報