nnahitoのサーバをなんとなくレンタルサーバに移動させました。
そしたらDBの設定がいじれなくて、full text searchでn-gramが使えず、記事が一切マッチングしなくなりました。
それを直したお話。
ngramってなに?
文字をn個の塊で考えることです。
例:今日は渋谷に行く
↓
今日
日は
は渋
谷に
に行
行く
こんな感じです。
これはngramのうちの2gram(bi-gram)です。
N=2ですね。
tri-gram(N=3)だと、
今日は
日は渋
は渋谷
渋谷に
谷に行
に行く
ですね。
これを使うと、日本語でもある程度マッチングしますが、それが使えなかったというお話。
検索用のテーブル/カラムを作る
じゃあどうするか。
検索用のカラムを作ってやればいい。
MySQLのデフォルトのfull text searchは半角スペース区切りで文字列を区切り、Indexをリスト化します。
英語だとわかりやすいですよね?
I have an apple
↓
I have an apple
と、このようにスペースでわけます。
しかし、日本語はスペース区切りの文法じゃありません。
私はりんごを持っています
↓
私 は りんご を 持っ て い ます
はい、むずいですよね。
これを解決するのが形態素解析です。
ただ今回はレンタルサーバ。
Pythonをぶっこむのも一苦労です。
じゃあどうするか。
精度は落ちますが、TinySegmenter PHPを使います。
文字を重み付けしていき、単語に区切るという、すげー発想です。天才じゃねーか?
なので、辞書がなくても動きます。やべーよ。
ということでこれを利用し、文章を形態素解析し、スペース区切りにしてあげます。
そしてそれをfull text searchのindexが貼られたカラムに突っ込み、検索の際にそちらを参照します。
そして検索の際に入力されたテキストも半角スペース区切りにしてSQLにぶっこみます。
検索SQLはこんな感じになります
SELECT *
FROM article_search_index
WHERE MATCH(search_content) AGAINST ('私 りんご' IN NATURAL LANGUAGE MODE);
これでそこそこの精度の日本語検索ができるようになりました。
ソースはこのブログの検索機能です。
以上