2007-11-04

Rubyで Sennaを使って全文検索を行う

全文検索エンジン Senna には Rubyバインディングが標準で添付されている。
N-GRAM, UTF-8キメ打ちですぐに Rubyから Sennaを使う手順をメモ。

まずはSennaをインストールする。今回は N-GRAM決め打ちなので MeCabは入れない。また、デフォルトエンコーディングをUTF-8にする。そのための configureは下記。
./configure --without-mecab --with-encoding=utf8

configureが終わったら make && make install で /usr/local 以下に Sennaがインストールされる。
NFKC正規化エンジンのコンパイルにものすごくメモリと時間がかかるので注意されたし。マシンがチープでどうしてもリソースが不足している場合はconfigureの時に --enable-nfkc=no を付ければその機能を外せるかもしれない。

Sennaのインストールが出来たらソースツリー内の bindings/ruby に移動し、ruby extconf.rb で Makefileを生成、make && make installすると Rubyバインディングがインストールされる。

Rubyから Sennaを使用するには require 'senna' とする。
下記はいくつかの呼び出し例。

■インデックスを新規作成する
index = Senna::Index::create("hoge",0,Senna::INDEX_NGRAM | Senna::INDEX_NORMALIZE)
これで
hoge.SEN
hoge.SEN.i
hoge.SEN.i.c
hoge.SEN.l
というファイルが作成される。これらがワンセットになってひとつのインデックスとなる。

■既に存在するインデックスをオープンする
index = Senna::Index::open("hoge")

■インデックスに文書を追加する
index.upd('123',nil,'ぎゃぼっ')
第一引数は文書ID(key)。任意のFixnumまたは文字列
第二引数は変更前文書の内容。追加の場合 nilまたは '' で良い。
第三引数はインデックスに追加したい文書の内容。

■インデックスから単一キーワードで文書を検索する
r = index.sel('ぎゃ')
if r != nil then
r.each {|key,score|
...
}
end


■インデックスをクローズする
index.close

Sennaはオリジナルの文書を保存しないため検索の実行結果は文書IDやスコアのみとなることに注意。
オリジナルの文書を保存する必要がある場合呼び出し側で行わなければならない。

プログラム言語への直接バインディングでは使い方が難しいという人には MySQLへの組み込み(Tritonn)やPostgreSQLへの組み込み(Ludia)をお勧めする。データベース側の環境設定やチューニングが難しいと感じるかもしれないが、SQLだけでインデックス作成と全文検索が実行できるためプログラムは簡単になる。

Sennaがなんだかエラーを返してきてうまく動かない場合は、/var/senna/log ディレクトリを作成して書き込めるようにパーミッション設定をするとログがそこに書き出されるので原因を探す助けになるかもしれない。必要に応じて自分で Sennaのソースにログ出力のコードを足しても良いだろう。

0 件のコメント:

コメントを投稿

<< ホーム