SennaのMySQL bindingをN-gramに
さきのエントリーでSennaは「N-gramインデックスを備え」と書いたが、N-gramにも対応しているというのが正しいかも。SennaをMySQLと連携させて使うときはSennaに付属のPatchを使うわけだけど、そのPatchではN-gramなインデックスをつくるようになっていません。mecabを利用した形態素解析がされています。せっかくなので、N-gramに対応させてみた。
Senna付属のPatchを当てた後のMySQLのソースコードをちょっと変更します。
「myisam/mi_open.c」の280行目(?)ぐらい
share->keyinfo[i].senna = sen_index_create(buf, sizeof(my_off_t), SEN_INDEX_NORMALIZE, 0, sen_enc_default);
これを
share->keyinfo[i].senna = sen_index_create(buf, sizeof(my_off_t), SEN_INDEX_NORMALIZE|SEN_INDEX_SPLIT_ALPHA|SEN_INDEX_SPLIT_DIGIT|SEN_INDE X_SPLIT_SYMBOL|SEN_INDEX_NGRAM, 0, sen_enc_default);
にします。
そして、
# make clean # ./configure # make;make install
とすればOK。インデックスは一度破棄して再作成する必要があります。
SennaのAPIの解説はこちらです。SEN_INDEX_*オブションはそれぞれ
SEN_INDEX_NORMALIZE
英文字の大文字/小文字、全角文字/半角文字を正規化してインデックスに登録する
SEN_INDEX_SPLIT_ALPHA
英文字列を文字要素に分割する
SEN_INDEX_SPLIT_DIGIT
数字文字列を文字要素に分割する
SEN_INDEX_SPLIT_SYMBOL
記号文字列を文字要素に分割する
SEN_INDEX_NGRAM
(形態素解析ではなく)n-gramを用いる
となっています。
ためしにぱどタウンのまち探検ナビのデータから5000件を登録するテストを行ってみましたが、なかなか快適に動きます。まち探検のナビキーワード検索をSennaに置き換えることを提案しています。