pythonのwhooshで全文検索してみる
全文検索、一度やってみたかったのよね。 whooshってのが手っ取り早そう。
という訳で、使ってみました。
import os
import whoosh.fields
import whoosh.index
import whoosh.qparser
# ディレクトリをインデックスとして使うらしい。
#  インデックスがすでにあるかどうかをチェック。
if os.path.exists('/tmp/index')
    # 既存のインデックスを開く
    ix = whoosh.index.open_dir('/tmp/index')
else:
    # インデックスの構造を定義
    schema = whoosh.fields.Schema(
        # IDはユニーク・・・ってわけでもないらしい。
        #  とりあえず、インデックス化はされないとのこと。
        name=whoosh.fields.ID(stored=True),
        # n-gramで保存されるデータ。
        #  全文検索する時はとりあえずこれだけで良いんじゃないだろうか。
        body=whoosh.fields.NGRAM(stored=True)
    )
    # インデックスを作成
    #  ディレクトリがないとエラーになるみたいなので、mkdirで作っとく。
    os.mkdir('/tmp/index')
    ix = whoosh.index.create_in('/tmp/index', schema)
# インデックスを更新するためのものを作成
writer = ix.writer()
# データを追加してみる
#  unicode型限定なので注意。
writer.add_document(name=u'aa', body=u'hello whoosh')
writer.add_document(name=u'bb', body=u'whoosh test')
writer.add_document(name=u'cc', body=u'test string')
# 更新したら必ずコミットする
writer.commit()
# 取り敢えず検索
#  クエリを作成
parser = whoosh.qparser.QueryParser('body', ix.schema)
query = parser.parse(u'whoosh')
#  そしたら検索。
#   aa u'hello whoosh'
#   bb u'whoosh test'
#   みたいに表示されるはず。
results = ix.searcher().search(query)
for r in results:
    print r['name'], repr(r['body'])
# データを削除する
#  writerを作りなおさないといけないので。注意。
query = parser.parse(u'test')
writer = ix.writer()
writer.delete_by_query(query)
writer.commit()
# もっかい検索してみる
#  bbが削除されているので、aaのみが表示されるはず。
query = parser.parse(u'whoosh')
for r in ix.searcher().search(query):
    print r['name'], repr(r['body'])
だいたいこんなもんだろうか。 データの更新は、一旦削除してから追加し直すみたいね。
全体的に、ちょっとめんどい感じ。 もうちょいシンプルでいいから、なんか良いの無いかな・・・。
とはいえ、速度はすごい速いです。 インデックスの作成に時間が掛かる代わりに、検索が高速。
これで手頃に扱えると嬉しいんだけどねー・・・。ラッパーでも作ろうかしら。
参考: