MySQL全文検索 の変更点 - アールメカブ

アールメカブ


MySQL全文検索 の変更点


[[DataBase]]

[[ここ:http://face-products.com/modules/wordpress/index.php?p=154]]から引用

MySQLで日本語の全文検索

#contents

MySQLで全文検索するには、
1. カラムに対して全文検索インデックス(FULLTEXT)を張ります
* カラムに対して全文検索インデックス(FULLTEXT)を張ります [#u599057a]

例)

    ALTER TABLE ‘xoops_table’ ADD FULLTEXT (myindex);


2. insertやupdateすると、自動的にインデックス化されます
* insertやupdateすると、自動的にインデックス化されます [#sbbe5fae]

    insert into xoops_table(myindex) values(’This is black ballpen.’);


3. 次に、MATCH … AGAINST 構文を使ったSELECT文で検索します
* 次に、MATCH … AGAINST 構文を使ったSELECT文で検索します [#r26d81e5]

    select * from xoops_table where match( myindex ) against( ‘black’ );


こんな感じの処理になります。
LIKE構文を使ったselect文と比較すると、数十倍高速なのです。


※関連記事の表示でも使用してます


■日本語で検索する場合
* 日本語で検索する場合 [#i2365bb7]
上の例で、select文に「against(’映画’)」と書いても、「映画」という文字列があったとしてもヒットしません。

そこでとりあえず簡単に日本語で検索してヒットさせるには
「IN BOOLEAN MODE」を使用すると日本語でもヒットします

例)

    select * from xoops_table where match( myindex )
    against(’映画’ IN BOOLEAN MODE);



■日本語での制限
*日本語での制限 [#f05ee15b]
これは私もハマったのですが、具体例で説明しますと


例)元テーブルの文字列

[映画] ナショナルトレジャー リンカーン暗殺者の日記.avi

ヒットする例:
 ・映画
 ・ナショナルトレジャー
 ・リンカーン暗殺者の日記

ヒットしない例:
 ・ナショナル
 ・トレジャー
 ・暗殺者

なぜ検索でヒットしたり、しなかったりするかというと

 検索したい文字列の前後が半角文字ならヒットする
 検索したい文字列の前後に日本語があるとヒットしない

という違いによるものだとわかりました。

つまり、インデックス(FULLTEXT)化する日本語の文字列は、
事前に形態素解析 (わかち書き)しておくとヒットするようになります。


わかち書きしておくことで
[ 映画 ] ナショナル トレジャー リンカーン 暗殺者 の 日記 . avi

こんな感じに バラバラになる >> 前後が半角文字になる >> ヒットする
というわけです。


■日本語で検索の応用
* 日本語で検索の応用 [#c8326644]
上の例では、半角スペースで区切ってありましたが
[ . : など、半角文字ならヒットしましたので、その仕様をうまく使えば
「日本語でWordPressの関連記事」を表示させることが出来ます。

RelatedEntriesは、本文中にキーワードを
<!−−kw=映画 トレジャー−−> という感じに登録すると、キーワードは登録されて
<!−−映画 トレジャー−−> のように文字列だけ本文に残ります。

そこで、あとでキーワードとしてヒットさせたい文字が本文中に残ります。
先ほどの説明の通り、キーワードの前後が半角です!

つまり、「映画」と「トレジャー」というキーワードは
関連する記事としてヒットするようになります。


ただし デフォルト状態だと、"cat" "dog" "マウス" などの検索語はすべて、「4文字未満の単語」として、無視されてしまいます。公式マニュアルのコメント部分でも、英語圏の方々が「えぇー、それはおかしいっしょ?」と異議申し立てをしていますが、デフォルト仕様はそうなっています。
* 4文字未満の単語 [#k7522ac7]
デフォルト状態だと、"cat" "dog" "マウス" などの検索語はすべて、「4文字未満の単語」として、無視されてしまいます。公式マニュアルのコメント部分でも、英語圏の方々が「えぇー、それはおかしいっしょ?」と異議申し立てをしていますが、デフォルト仕様はそうなっています。

変更方法) root権限にて、/etc/my.cnf 等に対して下記の記述を追加することで任意の文字数に変更できるようです:

 [mysqld]
 ft_min_word_len=1

記述後、変更を有効にするためには mysqld を再起動した上で、FULLTEXTインデックスを再作成する必要があります。