まず、基本的なライブラリーと辞書は(この記事を書いている時点では).tar.gzバイナリーに同梱されているっぽいのでそちらを使う。Oracle公式のyumリポジトリー からインストールできるrpmには含まれていないように見えるので、その場合は別途突っ込まないといけないはずだけど、libpluginmecab.soが何かにダイナミックリンクしているわけではないので、辞書だけ取ってきてmecabrcに設定すればいけるような気がする。詳しく調べてない。
この環境はバイナリーの.tar.gzを取ってきて、/usr/local/mysqlに展開したとして、
$ ll /usr/local/mysql/lib/plugin/*mecab* -rwxr-xr-x 1 root root 3988451 Feb 10 20:28 /usr/local/mysql/lib/plugin/libpluginmecab.so $ ll -R /usr/local/mysql/lib/mecab /usr/local/mysql/lib/mecab/: total 8 drwxr-xr-x 5 root root 4096 Feb 17 10:54 dic drwxr-xr-x 2 root root 4096 Feb 23 21:59 etc ..
plugin_dirにあたるlib/pluginにlibpluginmecab.soが、その他InnoDB MeCab Pluginに必要な辞書(dic)とか設定ファイル(etc)をおさめたディレクトリがlib/mecabにある。
続いてmy.cnfをゴニョる。
$ vim /etc/my.cnf .. [mysqld] loose-mecab-rc-file= /usr/local/mysql/lib/mecab/etc/mecabrc innodb_ft_min_token_size= 1 ..
mecab-rc-fileはlib/mecab/etc/mecabrcのパスを絶対パスで[mysqld]セクションに記述する。loose-接頭辞をつけておかないとMySQLが起動しなくなるので注意(INSTALL PLUGIN前にこのオプションを渡そうとすると、"unknown option"って言われてmysqldが起動してくれない)
参考: MySQL の unknown option エラーはオプションに loose- プレフィックスをつけると回避できる - かみぽわーる
my.cnfの次はmecabrc(↑のmy.cnfに記述したパスにあるもの)をゴニョる。
$ vim /usr/local/mysql/lib/mecab/etc/mecabrc .. dicdir = /usr/local/mysql/lib/mecab/dic/ipadic_utf-8
dicdirに、使いたい辞書の入っているディレクトリを指定する。
# ll lib/mecab/dic/ total 12 drwxr-xr-x 2 root root 4096 Feb 17 10:54 ipadic_euc-jp drwxr-xr-x 2 root root 4096 Feb 17 10:54 ipadic_sjis drwxr-xr-x 2 root root 4096 Feb 17 10:54 ipadic_utf-8
5.7.6現在、euc-jp, sjis, utf-8の3つが入ってる。5.7.7のリリースノート を見ると eucjpms, cp932, utf8mb4に対応したよ! と書いてあって、マニュアルのページには同じ辞書を使うよ、と書いてある。
この状態で起動してやると、
$ bin/mysqld_safe & $ less data/error.log .. 2015-03-04T02:30:12.628925Z 0 [Warning] unknown variable 'loose-mecab-rc-file=/usr/local/mysql/lib/mecab/etc/mecabrc' ..
まだINSTALL PLUGINしてないので、unknown variableとして扱われる。
mysql> INSTALL PLUGIN mecab SONAME 'libpluginmecab.so'; Query OK, 0 rows affected (0.20 sec) $ tail data/error.log 2015-03-04T03:21:46.236551Z 2 [Note] Mecab: Trying createModel(--rcfile=/usr/local/mysql/lib/mecab/etc/mecabrc) 2015-03-04T03:21:46.436600Z 2 [Note] Mecab: Loaded dictionary charset is utf-8
認識したぽい。
mysql> SHOW CREATE TABLE articles; +----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Table | Create Table | +----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | articles | CREATE TABLE `articles` ( `seq` bigint(20) unsigned NOT NULL AUTO_INCREMENT, `title` text, `content` longtext, `timestamp` datetime DEFAULT NULL, UNIQUE KEY `seq` (`seq`), KEY `timestamp` (`timestamp`) ) ENGINE=InnoDB AUTO_INCREMENT=1914065 DEFAULT CHARSET=utf8 | +----------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)
こんな感じのWikipediaのデータを食わせたテーブルに
mysql> ALTER TABLE articles ADD FULLTEXT KEY (title, content) WITH PARSER MeCab; Query OK, 0 rows affected (1 hour 2 min 12.62 sec) Records: 0 Duplicates: 0 Warnings: 0 $ tail data/error.log 2015-03-04T03:39:02.484153Z 0 [ERROR] Mecab: 2015-03-04T03:40:06.299126Z 0 [ERROR] Mecab: 2015-03-04T03:45:13.146195Z 0 [ERROR] Mecab: 2015-03-04T03:56:10.793337Z 0 [ERROR] Mecab: 2015-03-04T03:56:21.149414Z 0 [ERROR] Mecab: 2015-03-04T03:59:34.385256Z 0 [ERROR] Mecab: 2015-03-04T03:59:34.421553Z 0 [ERROR] Mecab: 2015-03-04T03:59:34.470875Z 0 [ERROR] Mecab: 2015-03-04T03:59:34.600808Z 0 [ERROR] Mecab: 2015-03-04T03:59:34.632828Z 0 [ERROR] Mecab: 2015-03-04T03:59:34.941143Z 0 [ERROR] Mecab: 2015-03-04T03:59:34.969369Z 0 [ERROR] Mecab: 2015-03-04T03:59:34.986076Z 0 [ERROR] Mecab: 2015-03-04T03:59:35.056543Z 0 [ERROR] Mecab: 2015-03-04T03:59:35.352131Z 0 [ERROR] Mecab: 2015-03-04T03:59:36.754206Z 0 [ERROR] Mecab:
なんかダイイングメッセージみたいに不明なエラー吐いてるけど(Mroongaと比較した感じでは"too long sentence"エラーのはず)取り敢えず無視して、
【2015/03/18 13:33】
バグレポートしましたが、5.7.8でFixedとのこと。
MySQL Bugs: #76164: InnoDB FTS with MeCab parser prints empty error message
mysql> SELECT COUNT(*) FROM articles WHERE match(title, content) against('データベース'); +----------+ | COUNT(*) | +----------+ | 3013 | +----------+ 1 row in set (0.01 sec) mysql> explain SELECT COUNT(*) FROM articles WHERE match(title, content) against ('データベース'); +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ | 1 | SIMPLE | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | NULL | Select tables optimized away | +----+-------------+-------+------------+------+---------------+------+---------+------+------+----------+------------------------------+ 1 row in set, 1 warning (0.01 sec) mysql> SHOW WARNINGS; +-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Level | Code | Message | +-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ | Note | 1003 | /* select#1 */ select count(0) AS `COUNT(*)` from `wikipedia`.`articles` where (match `wikipedia`.`articles`.`title`,`wikipedia`.`articles`.`content` against ('データベース')) | +-------+------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ 1 row in set (0.02 sec)
引けてるっぽい。
mysql> explain SELECT * FROM articles WHERE match(title, content) against ('データベース') LIMIT 10; +----+-------------+----------+------------+----------+---------------+-------+---------+-------+------+----------+-------------------------------------------+ | id | select_type | table | partitions | type | possible_keys | key | key_len | ref | rows | filtered | Extra | +----+-------------+----------+------------+----------+---------------+-------+---------+-------+------+----------+-------------------------------------------+ | 1 | SIMPLE | articles | NULL | fulltext | title | title | 0 | const | 1 | 100.00 | Using where; Ft_hints: sorted, limit = 10 | +----+-------------+----------+------------+----------+---------------+-------+---------+-------+------+----------+-------------------------------------------+ 1 row in set, 1 warning (0.02 sec) mysql> SELECT * FROM articles WHERE match(title, content) against ('データベース') LIMIT 10; .. 10 rows in set (0.01 sec)
バッファプールに載ってて単一条件ならまあまあ動くんだけど
mysql> SELECT * FROM articles WHERE match(title, content) against ('データベース') ORDER BY timestamp DESC LIMIT 10; .. 10 rows in set (0.62 sec)
スコア以外のところでソートするとやっぱり死ねるねぇ。。
【2015/03/10 18:57】
Ngramの方も書きました => 日々の覚書: MySQL 5.7.6のInnoDB日本語全文検索 ngram
0 件のコメント :
コメントを投稿