経緯
MySQL5.6 の、InnoDB にバイグラムでフルテキストインデックスを作っているのですが、
TWIN という文字を検索しようとした所、
SELECT COUNT(*) FROM ...
WHERE MATCH(search_text) AGAINST ('+tw +wi +in' IN BOOLEAN MODE)
... 結果が出てきません。
'+tw +wi' だと結果があります(twin がヒットします)。
調査した所、「ストップワード」という機能があり、in や by, is なんかは検索インデックスが作られないようになっている仕様でした。
※ InnoDB のフルテキストインデックスの場合のみ。MyISAM の場合は、デフォルトはストップワードテーブルは使われない。
ストップワードの内容を表示するには
SELECT * FROM INFORMATION_SCHEMA.INNODB_FT_DEFAULT_STOPWORD;
in, is, it, la, of, on などが入ってます。
このテーブルは、自分で別のテーブルを作ってそちらを使うように設定もできますが、今回はそもそもストップワードテーブルを使ってのインデックス生成フィルタリングを無効にします。
無効にせず、ストップワードテーブルを差し替えるにはこちらのページが参考になります。
MySQL :: MySQL 5.6 リファレンスマニュアル :: 12.9.4 全文ストップワード
https://dev.mysql.com/doc/refman/5.6/ja/fulltext-stopwords.html
ストップワードを無効にする設定
InnoDB でのストップワード判定を無効にするには、設定の innodb_ft_enable_stopword を変更します。
現状の確認
SHOW VARIABLES LIKE 'innodb_ft_enable_stopword';
innodb_ft_enable_stopword ON
デフォルトでは有効になっています。
なので、my.cnf などの設定ファイルに
[mysqld]
innodb_ft_enable_stopword = OFF
として、MySQL を再起動すると
SHOW VARIABLES LIKE 'innodb_ft_enable_stopword';
innodb_ft_enable_stopword OFF
反映されます。
Ubuntu なんかでは、 /etc/mysql/conf.d/ ディレクトリが用意されているので、その中に設定ファイルを放り込むと良いでしょう。
僕のはこんな感じ
/etc/mysql/conf.d/fulltext_search.cnf
[mysqld]
# Fulltext search bigram settings.
ft_min_word_len = 2
innodb_ft_min_token_size = 2
innodb_ft_enable_stopword = OFF
検索インデックスの再生成
インデックスの再生成は、
REPAIR TABLE table_name QUICK; ではなく (これは MyISAM の場合)
InnoDB の場合は
ALTER TABLE table_name FORCE;
で行えます。
SELECT COUNT(*) FROM ...
WHERE MATCH(search_text) AGAINST ('+tw +wi +in' IN BOOLEAN MODE)
→ 結果でました!