Whoosh中国語検索

5245 ワード

Whoosh+jieba中国語検索**
背景最近のプロジェクトはWhooshの1つのPythonが书いたインデックス検索モジュールを使って、比较的に少ない中国语の资料を発见してしかも先辈のコードを见ても分からないことが多いことを発见して、だから自分で公式サイトのドキュメントのドキュメントに従って1回かき混ぜて、私の自分の理解と公式サイトのいくつかのよく分からない解釈を书きます.
いくつかのコアオブジェクトをすばやく手に入れる
IndexオブジェクトとSchemaオブジェクト
Whooshを使用する前に、まずindexオブジェクトを作成する必要があります.indexオブジェクトはグローバルインデックスです.indexオブジェクトを作成する前に、indexオブジェクトのいくつかのプロパティを宣言する必要があります.そのため、これらのプロパティをパッケージするschemaオブジェクトを作成する必要があります.schemaには多くのFieldsがあります(1つのFieldはindexオブジェクトの情報ブロックです.つまり、私たちが検索する必要があるコンテンツです).
栗を挙げると、次のコードは「title」と「path」と「content」の3つのFieldsを含むschemaオブジェクトを作成します.
from whoosh.Fields import Schema,TEXT,ID schema=Schema(title=TEXT,path=ID,content=TEXT)schemaオブジェクトを作成する際には、前述のtitle=TEXT
schemaオブジェクトを作成したらcreate_を使用します.inメソッドによるschemaのインデックスの作成
import os.path
from whoosh.index import create_in
if not os.path.exists("index"):
    os.mkdir("index")
idx = create_in("index", schema)

次に、作成したインデックスを次の2つの方法で開くことができます.
      FileStorage  
from whoosh.filedb.filestore import FileStorage
storage = FileStorage(idx_path)  #idx_path      
idx = storage.open_index(indexname=indexname, schema=schema)

      open_dir  
from whoosh.index import open_dir
idx = open_dir(indexname=indexname)  #indexname     

IndexWriterオブジェクト
Indexオブジェクトがあれば、検索する必要がある情報をindexに書き込む必要があるので、IndexWriterオブジェクトはadd_を提供するために使用されます.document(**kwargs)メソッドは、前に宣言した様々なFieldsにデータを書き込む
writer = idx.writer()  #IndexWriter  
writer.add_document(
    title=u"Document Title",
    path=u"/a",
    content=u"Hello Whoosh"
)  # Field   schema       
writer.commit()  #     document

次の点に注意してください.
各フィールドに値を割り当てる必要はありません.フィールドの値は必ずunicodeタイプの値です.インデックスとして保存するフィールドがある場合は、1つのunicode値をインデックスとして使用して別のオブジェクトを保存できます.writer.add_document(title=u"Title to be indexed", _stored_title=u"Stored title")非同期処理が必要な場合は、非同期IndexWriterオブジェクトを作成できます.
from whoosh.writing import AsyncWriter
writer = AsyncWriter(index=index)

BufferedWriterオブジェクトを作成するには、Bufferが必要です.
from whoosh.writing import BufferedWriter
period   commit       ,limit          
writer = BufferedWriter(index=index, period=120, limit=20)

Searcherオブジェクト
インデックスの検索を開始する前に、searcherオブジェクトを作成する必要があります.searcher = idx.sercher()しかし、一般的にはこのように検索器searcherを作成することはできません.これはインデックス検索が完了した後、検索器を閉じてメモリを解放することはできません(searcherがメモリを食べていることを知っていればいいです).私たちは一般的にwithを使ってsearcherオブジェクトを作成します.検索器の使用が完了した後、正しく閉じることを保証していません.
with idx.sercher() as searcher:
    ...

以上の書き方は
try:
    searcher = idx.searcher()
    ...
finally:
    searcher.close()

サーチのsearch()メソッドにはQueryオブジェクトを入力する必要があります.Queryオブジェクトを直接構築したり、query parserを使用してクエリーフィールドを解析したりすることができます.
くりを一つあげる
#         
from whoosh.query import *
myquery = And([Term("content", u"apple"), Term("content", "bear")]) 

デフォルトのQueryParserでは、クエリ原語ANDとORとNOTをSQLのように簡単に使用できます!
解析器を使用してクエリーフィールドを解析する
from whoosh.qparser import QueryParser
parser = QueryParser("content", idx.schema)
myquery = parser.parse(querystring)

クエリー・オブジェクトを構築したら、検索器のsearch()メソッドを使用して検索できます.
results = searcher.search(myquery)
print(results[0])
{"title": "Document", "content": "Hello Whoosh"}

より一般的には、ページングクエリsearchを使用します.Page()の方法results = searcher.search_page(myquery, page_num, page_len)注目すべきはsearch()がデフォルトパラメータweighting=BM 25 Fを受信することである.これはwhooshである.scoring.Weightingオブジェクトは、組み込まれたscoreメソッドを使用して検索の優先度を計算し、ドキュメントインデックスをクエリーします.
jieba分詞と組み合わせて使用
Whooshの基本的な使い方は以上の通りです.次にQueryStringに結巴分詞分析モジュールを追加します.
jieba 0.30以降のバージョンではWhoosh用の分詞インタフェース:ChineseAnalyzerが追加されているので便利です
まずWhoosh schemaオブジェクトの作成でwhoosh.fields.TEXT、TEXTを宣言するデフォルトのフィールドのFieldAttributesデフォルトには属性analyzerがあります
analyzerはcallマジックメソッドを持つクラスで、TEXTワードドメインの分析を行い、呼び出すとTEXTドメインの値をcall処理します.
analyzerが受信したパラメータはunicode文字列で、戻り値は文字列カットで、栗を挙げる
e.g.(
​ param = “Mary had a little lamb”
​ return = [“Mary”, “had”, “a”, “little”, “lamb”]
)
WhooshのStandardAnalyzerを使用しており、英語の分詞器です.jiebaに接続して中国語の分詞を作るためには、TEXT(analyzer=analysis.StandardAnalyzer()をjiebaのChineseAnalyzerに置き換える必要があります
from __future__ import unicode_literals
from jieba.analyse import ChineseAnalyzer

analyzer = ChineseAnalyzer()

schema = Schema(title=TEXT(stored=True), path=ID(stored=True), content=TEXT(stored=True, analyzer=analyzer))

idx = create_in("test", schema)
writer = idx.writer()
writer.add_document(
    title="test-document",
    path="/c",
    content="This is the document for test"
)
writer.commit()
searcher = idx.searcher()
parser = QueryParser("content", schema=idx.schema)

for keyword in ("  "," ","first","  ","   ","  "):
    print("result of ",keyword)
    q = parser.parse(keyword)
    results = searcher.search(q)
    for hit in results:
        print(hit.highlights("content"))
    print("="*10)