Python Whoosh入門帖


概要
Whooshは、テキストをインデックスし、インデックスに基づいて検索できるクラスとメソッドを含むクラスライブラリです.自分のコンテンツに対する検索エンジンを開発することができます.たとえば、ブログソフトウェアを作成したい場合は、Whooshを使用してブログクラスを検索できる検索機能を追加できます.
使用方法
index,schema,field
Whooshの使用を開始するには、インデックスのオブジェクトが必要です.最初に使用する場合は、インデックスを作成し、インデックスのschemaを定義する必要があります.schemaにインデックスをリストするフィールド.1つのフィールドは、見出しやドキュメントの内容など、インデックス内の各ドキュメントの情報です.1つのフィールドは、同時に格納されてインデックス化されてもよいし、そのうちの1つのみ(インデックス化されていることは検索可能であることを意味し、格納されていることは、インデックスを取得する値が結果とともに返されることを意味し、この特性はフィールドがタイトルである場合に便利である).
次のschemaには、「title」と「content」の2つのフィールドがあります.
from whoosh.fields import Schema, TEXT
schema = Schema(title=TEXT, content=TEXT)

インデックスを作成する場合は、schemaを1回作成するだけです.schemaはシーケンス化され、インデックスに格納されます.schemaオブジェクトを作成すると、キーワードパラメータを使用してフィールド名をフィールドタイプにマッピングします.フィールドとそのタイプのリストは、インデックスと検索可能な内容を定義します.Whooshは比較的有用なフィールドタイプを多く定義しており、自分のフィールドを簡単に定義することができます.
whoosh.fields.ID

このタイプは、アドレス、URK、日付、タイプなどのフィールドで使用する場合に便利な、すべてのフィールドの値(切断されない)を1つのセルとしてインデックスします(格納するかどうかも選択できます).
whoosh.fields.STORED

このフィールドはドキュメントとともに使用され、インデックスではありません.このフィールドタイプはインデックスおよび検索できません.ユーザーが検索結果を取得した場合、ドキュメント情報をどのように表示しますか.
whoosh.fields.KEYWORD

このタイプは、スペースまたはカンマ区切りキーワードのために設計されています.このタイプはインデックスと検索(オプションで格納するかどうか)できます.つまり、フレーズ検索はサポートされていません.
whoosh.fields.TEXT

This type is for body text. It indexes (and optionally stores) the text and stores term positions to allow phrase searching. これはファイルの内容タイプです.テキストと用語の場所をインデックス(オプションで格納されるかどうか)して、フレーズ検索を許可します.
whoosh.fields.NUMERIC

数値タイプ、格納整数および浮動小数点数
whoosh.fields.BOOLEAN

ブール型
whoosh.fields.DATETIME

時間オブジェクトwhoosh.fields.NGRAM and whoosh.fields.NGRAMWORDS
これらのタイプは、フィールドテキストまたは単一の用語をn元に分解します.詳細については、インデックスとn-グラムの検索を参照してください.
フィールドタイプにパラメータを渡す必要がない場合は、クラス名を1つだけ指定し、Whooshはインスタンスオブジェクトを返します.コードの例は次のとおりです.
from whoosh.fields import Schema, STORED, ID, KEYWORD, TEXT
schema = Schema(title=TEXT(stored=True), content=TEXT,
                path=ID(stored=True), tags=KEYWORD, icon=STORED)

Schemaがあればインデックスを作成できます
import os.path
from whoosh.index import create_in
if not os.path.exists("index"):
    os.mkdir("index")
ix = create_in("index", schema)

必要が低い場合は、インデックスを含むストレージオブジェクトが作成されています.1つのストレージ・オブジェクトは、インデックスが格納されていることを示します.通常は、インデックスをディレクトリ内のファイルのセットとして格納するファイルストレージです.
インデックスを作成すると、比較的便利な方法open_dirで開くことができます.
from whoosh.index import open_dir
ix = open_dir("index")

IndexWriterオブジェクト
OK、インデックスオブジェクトができました.ドキュメントの追加を始めます.インデックス・オブジェクトのwriterメソッドは、インデックスにドキュメントを追加できるIndexWriterオブジェクトを返します.IndexWriterのadd_document(**kwargs)メソッドは、フィールド名がVALUにマッピングされたキーワードパラメータを受け入れる
writer = ix.writer()
writer.add_document(title=u"My document", content=u"This is my document!",
                    path=u"/a", tags=u"first short", icon=u"/icons/star.png")
writer.add_document(title=u"Second try", content=u"This is the second example.",
                    path=u"/b", tags=u"second short", icon=u"/icons/sheep.png")
writer.add_document(title=u"Third time's the charm", content=u"Examples are many.",
                    path=u"/c", tags=u"short", icon=u"/icons/book.png")
writer.commit()

重要なヒント
  • すべてのフィールドの値を記入する必要はありません.Whooshは、ドキュメントのフィールドを漏らしたかどうかに注目しません.
  • は、したがってテキストフィールドにunicode値を渡さなければならない.格納されているだけであれば、シーケンス化可能な任意のオブジェクトを渡すことができる.

  • テキストフィールドの紀要インデックスと格納がある場合は、unicode値をインデックスできますが、必要に応じて異なるオブジェクトを使用して格納できます(通常はそうではありませんが、実際には役に立ちます).
    writer.add_document(title=u"Title to be indexed", _stored_title=u"Stored title")
    

    IndexWriterオブジェクトのcommitメソッドを呼び出してドキュメントをインデックスに書き込む
    writer.commit()
    

    ドキュメントがインデックスにコミットされ、検索できます.
    Searcherオブジェクト
    検索を開始するには、Searcherオブジェクトが必要です.
    searcher = ix.searcher()
    

    通常with文を使用して検索器を開くと、検索が完了すると自動的に検索器が閉じます(検索オブジェクトは開いているファイルの数を表しますので、表示せずに閉じ、OSの回収が遅い場合はファイルハンドルのオーバーフローに遭遇します).
    with ix.searcher() as searcher:
    

    次の操作は等価です.
    try:
        searcher = ix.searcher()
        ...
    finally:
        searcher.close()
    

    Searcherのsearch関数は、Queryオブジェクトを受け入れます.Queryオブジェクトの辞書を構築したり、Parserでクエリー文を解析したりすることができます.
    たとえば、このクエリはcontentフィールドに「apple」と「bear」を含むドキュメントに一致します.
    from whoosh.query import *
    myquery = And([Term("content", u"apple"), Term("content", "bear")])
    

    クエリー文字列を解析するには、QARSERモジュールのデフォルトクエリー解析器を使用します.最初のパラメータは、検索するデフォルトのフィールドです.テキストコンテンツフィールドでよく使用されます.2番目のオプションパラメータは、フィールドの解析方法を理解するためのschemaです.
    from whoosh.qparser import QueryParser
    parser = QueryParser("content", ix.schema)
    myquery = parser.parse(querystring)
    

    Searcherとqueryのオブジェクトがある場合は、Searcherのsearch()関数を使用してクエリーを実行し、検索結果オブジェクトを得ることができます.
    results = searcher.search(myquery)
    print(len(results))
    1
    print(results[0])
      
    {"title": "Second try", "path": "/b", "icon": "/icons/sheep.png"}
    

    デフォルトのQueryParserは、Luceneによく似たクエリー言語を実現しています.ANDまたはORを使用して文を接続し、NOTを使用して文を除外し、文をカッコ付きの句に結合し、範囲、接頭辞、ワイルドカードクエリーを実行し、検索する異なるフィールドを指定できます.デフォルトでは、句はANDと結合されます(したがって、デフォルトでは、指定したすべての用語はドキュメントで一致する必要があります):
    print(parser.parse(u"render shade animate"))
    And([Term("content", "render"), Term("content", "shade"), Term("content", "animate")])
    print(parser.parse(u"render OR (title:shade keyword:animate)"))
    Or([Term("content", "render"), And([Term("title", "shade"), Term("keyword", "animate")])])
    print(parser.parse(u"rend*"))
    Prefix("content", "rend")
    

    検索結果には、whooshにはいくつかの拡張機能があります.
  • は、Relelvicesによるソートではなく、インデックスフィールドの値で結果をソートします.
  • オリジナルドキュメントの抜粋で検索語を強調します.
  • クエリーされたドキュメントに基づいてクエリー文を拡張します.
  • 結果をページング(例えば「結果1-20を表示し、4ページ目1ページ目」)
  • .
    次に、完全な例を示します.
    from whoosh.index import create_in
    from whoosh.fields import *
    schema = Schema(title=TEXT(stored=True), path=ID(stored=True), content=TEXT)
    ix = create_in("indexdir", schema)
    writer = ix.writer()
    writer.add_document(title=u"First document", path=u"/a", content=u"This is the first document we've added!")
    writer.add_document(title=u"Second document", path=u"/b",content=u"The second one is even more interesting!")
    writer.commit()
    from whoosh.qparser import QueryParser
    with ix.searcher() as searcher:
        query = QueryParser("content", ix.schema).parse("first")
        results = searcher.search(query)
        results[0]