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'])
だいたいこんなもんだろうか。 データの更新は、一旦削除してから追加し直すみたいね。
全体的に、ちょっとめんどい感じ。 もうちょいシンプルでいいから、なんか良いの無いかな・・・。
とはいえ、速度はすごい速いです。 インデックスの作成に時間が掛かる代わりに、検索が高速。
これで手頃に扱えると嬉しいんだけどねー・・・。ラッパーでも作ろうかしら。
参考: