(この記事は InnoDB Full-Text: MeCab Parser を Yoshiaki Yamasaki が翻訳したものです)
このブログ記事で紹介した一般的なCJK(中国語、日本語、韓国語)のサポートに加えて、私達はMeCabパーサーも追加しました。MeCabは日本語の形態素解析エンジンで、私達は今MeCabをベースにした全文検索プラグインパーサーを持っています!
使用方法
- mecab_rc_fileオプションを設定する — mecab_rc_fileはMeCabパーサーに関連する読み取り専用のシステム変数です。mecab_rc_fileが指すmecabrcファイルはMeCabが必要とする設定ファイルです。そして、MeCabに辞書をどこからロードすればいいかを伝えるために、
dicdir=/path/to/ipadicというエントリが必要です。MySQLがインストールされると、デフォルトでバンドルされているmecabrcファイルは
/path/to/mysql/install/lib/mecab/etc/mecabrcにあります。また、ipadic_euc-jp, ipadic_sjis, ipadic_utf-8という3つの辞書が
/path/to/mysql/install/lib/mecab/dicディレクトリにあります。私たちはこれら3つの内から使用したい辞書を1つ指定するために、mecabrcファイルを修正する必要があります。
注意:あなたが独自の辞書を持っている場合は、代わりにその辞書を使用できます。mecabrcファイル内で指定できる多くの追加オプションも有ります。設定ファイルの詳細に関しては、こちらのマニュアルを参照して下さい。ここではテスト目的で、以下の手順でipadic_utf-8をロードしてみましょう。(以下の例では、MySQL 5.7.7は/usr/local/mysqlにインストールされています) :- この様なエントリをmecabrcファイルに追加します:
dicdir=/usr/local/mysql/lib/mecab/dic/ipadic_utf-8 - この様なエントリを/etc/my.cnfファイルの[mysqld]セクションに追加します:
loose-mecab-rc-file=/usr/local/mysql/lib/mecab/etc/mecabrc
- この様なエントリをmecabrcファイルに追加します:
- innodb_ft_min_token_sizeを設定します— MeCabパーサーを使う場合の推奨値は1もしくは2です(デフォルト値は3です)。以下の例では1を使用します。
- MeCabプラグインをインストール:
12345678910mysql> INSTALL PLUGIN mecab SONAME 'libpluginmecab.so';Query OK, 0 rows affected (0.09 sec)mysql> SHOW STATUS LIKE 'mecab_charset';+---------------+-------+| Variable_name | Value |+---------------+-------+| mecab_charset | utf8 |+---------------+-------+1 row in set (0.00 sec) - MeCabパーサーを使って全文検索インデックスを作成
(注意:MySQL 5.7.6では、utf8mb4の代わりにut8を指定する必要があります。
The MeCab parser plugin now supports the eucjpms, cp932, and utf8mb4 character sets in 5.7.7 and later—Bug#20534096):
1234567mysql> CREATE TABLE articles(FTS_DOC_ID BIGINT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,title VARCHAR(100),FULLTEXT INDEX mecab_idx (title) WITH PARSER mecab)ENGINE=InnoDB CHARACTER SET utf8mb4;Query OK, 0 rows affected (1.27 sec)
MeCabトークン化の詳細
トークン化がどのように行われるのかを明確に示す例を見てみましょう:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
mysql> set names utf8mb4; Query OK, 0 rows affected (0.00 sec) mysql> INSERT INTO articles (title) VALUES ('東京都は日本の首都です'),('京都と大阪は日本の府です'); Query OK, 2 rows affected (0.37 sec) Records: 2 Duplicates: 0 Warnings: 0 mysql> SET GLOBAL innodb_ft_aux_table="test/articles"; Query OK, 0 rows affected (0.00 sec) mysql> SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_INDEX_CACHE ORDER BY doc_id, position; +--------+--------------+-------------+-----------+--------+----------+ | WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID | POSITION | +--------+--------------+-------------+-----------+--------+----------+ | 東京 | 1 | 1 | 1 | 1 | 0 | | 都 | 1 | 1 | 1 | 1 | 6 | | は | 1 | 2 | 2 | 1 | 9 | | 日本 | 1 | 2 | 2 | 1 | 12 | | の | 1 | 2 | 2 | 1 | 18 | | 首都 | 1 | 1 | 1 | 1 | 21 | | です | 1 | 2 | 2 | 1 | 27 | | 京都 | 2 | 2 | 1 | 2 | 0 | | と | 2 | 2 | 1 | 2 | 6 | | 大阪 | 2 | 2 | 1 | 2 | 9 | | は | 1 | 2 | 2 | 2 | 15 | | 日本 | 1 | 2 | 2 | 2 | 18 | | の | 1 | 2 | 2 | 2 | 24 | | 府 | 2 | 2 | 1 | 2 | 27 | | です | 1 | 2 | 2 | 2 | 30 | +--------+--------------+-------------+-----------+--------+----------+ 15 rows in set (0.00 sec) |
MeCabを使った全文検索の詳細
テキスト検索
- NATURAL LANGUAGE MODEでは、検索されるテキストは検索トークンの和集合に変換されます。例えば、’日本の首都’は’日本 の 首都’に変換されます。ここで具体例を紹介します:
12345678mysql> SELECT * FROM articles WHERE MATCH(title) AGAINST('日本の首都' IN NATURAL LANGUAGE MODE);+------------+--------------------------------------+| FTS_DOC_ID | title |+------------+--------------------------------------+| 1 | 東京都は日本の首都です || 2 | 京都と大阪は日本の府です |+------------+--------------------------------------+2 rows in set (0.00 sec) - BOOLEAN MODEでは、検索されるテキストはフレーズ検索に変換されます。例えば、’日本の首都’は'”日本 の 首都”‘に変換されます。ここで具体例を紹介します:
1234567mysql> SELECT * FROM articles WHERE MATCH(title) AGAINST('日本の首都' IN BOOLEAN MODE);+------------+-----------------------------------+| FTS_DOC_ID | title |+------------+-----------------------------------+| 1 | 東京都は日本の首都です |+------------+-----------------------------------+1 row in set (0.01 sec)
ワイルドカードを使った検索
- ワイルドカードを使った検索はトークナイズされません。例えば、’日本の首都*’は接頭辞’日本の首都’を検索します。そして、一致する結果が得られないかもしれません。ここで2つの具体例を紹介します:
1234567891011mysql> SELECT * FROM articles WHERE MATCH(title) AGAINST('日本*' IN BOOLEAN MODE);+------------+--------------------------------------+| FTS_DOC_ID | title |+------------+--------------------------------------+| 1 | 東京都は日本の首都です || 2 | 京都と大阪は日本の府です |+------------+--------------------------------------+2 rows in set (0.00 sec)mysql> SELECT * FROM articles WHERE MATCH(title) AGAINST('日本の首都*' IN BOOLEAN MODE);Empty set (0.00 sec)
フレーズ検索
- フレーズ検索はMeCabによってトークナイズされます。例えば、”日本の首都”は”日本 の 首都”に変換されます。ここで具体例を紹介します:
1234567mysql> SELECT * FROM articles WHERE MATCH(title) AGAINST('"日本の首都"' IN BOOLEAN MODE);+------------+-----------------------------------+| FTS_DOC_ID | title |+------------+-----------------------------------+| 1 | 東京都は日本の首都です |+------------+-----------------------------------+1 row in set (0.00 sec)
MeCabの制限
サポートしているキャラクタセットはeucjpms (ujis), cp932 (sjis), utf8 (utf8mb4)の3つです。MeCabが使用しているキャラクタセットとInnoDBが使用しているキャラクタセットに違いがある場合(例えばMeCabのキャラクタセットがujisで、全文検索インデックスがutf8/utf8mb4の場合)、検索しようとした時にキャラクタセット不一致のエラーが発生します。
InnoDBの全文検索全般に関して詳細を知りたい場合は、ユーザーマニュアルのInnoDB Full-Text Index セクションや、ジミーの素晴らしい記事(Dr. Dobb’s article) を参照して下さい。MeCabパーサーに関する詳細は、ユーザーマニュアルのMeCab parserセクションを参照して下さい。
私達はこの新しい機能が役立つことを願っています!私たちはMySQL 5.7を通して全文検索がCJK対応したことをとても嬉しく思っていますし、この改善はMySQL 5.7の改善点の中でも大きなものです。ご質問があれば、このブログにコメントして頂くか、サポートにお問合せ下さい。もし、バグを見つけた場合は、このブログにコメントして頂くか、バグレポートに投稿して頂くか、サポートにお問合せ下さい。
いつもMySQLをご利用いただき、ありがとうございます!