Whoosh+jieba中国語検索
5682 ワード
背景
最近、プロジェクトはWhooshのPythonが作成したインデックス検索モジュールを使います.中国語の資料が少なく、先輩のコードを見ても分からないことが多いことに気づきました.だから、自分で公式サイトのドキュメントに従って、自分の理解と公式サイトのよくない説明を書きました.
クイックハンド
いくつかのコアオブジェクト
Whooshを使用する前に、まずindexオブジェクトを作成する必要があります.indexオブジェクトはグローバルインデックスです.indexオブジェクトを作成する前に、indexオブジェクトのいくつかのプロパティを宣言する必要があります.そのため、これらのプロパティをパッケージするschemaオブジェクトを作成する必要があります.schemaには多くのFieldsがあります(1つのFieldはindexオブジェクトの情報ブロックです.つまり、私たちが検索する必要があるコンテンツです).
栗を挙げると、次のコードは「title」と「path」と「content」の3つのFieldsを含むschemaオブジェクトを作成します.
schemaオブジェクトを作成するには、Field nameとField typeをキーワードでマッピングする必要があります.上記のように
次に、作成したインデックスを次の2つの方法で開くことができます.
indexオブジェクトがあると、検索する必要がある情報をindexに書き込む必要があるので
次の点に注意してください.フィールドごとに付与されるわけではない Field伝値は必ずunicodeタイプの値 インデックスとして保存するフィールドがある場合は、別のオブジェクトをインデックスとして保存しながらunicode値を使用できます.
非同期処理が必要な場合は、非同期IndexWriterオブジェクトを作成できます.
BufferedWriterオブジェクトを作成するには、Bufferが必要です.
インデックスの検索を開始する前に、searcherオブジェクトを作成する必要があります.
しかし、一般的にはこのように検索器searcherを作成することはできません.これはインデックス検索が完了した後、検索器を閉じてメモリを解放することはできません(searcherがメモリを食べていることを知っていればいいです).私たちは一般的に
以上の書き方は
検索器の
くりを一つあげる
デフォルトのQueryParserではクエリー原語の使用が許可されています
クエリー・オブジェクトを構築したら、検索器の
より一般的にはページングクエリ
注目すべきは
jieba分詞と組み合わせて使用
Whooshの基本的な使い方は以上の通りです.次にQueryStringに結巴分詞分析モジュールを追加します.
jieba 0.30以降のバージョンではWhoosh用の分詞インタフェース:ChineseAnalyzerが追加されているので便利です
まずWhoosh schemaオブジェクトの作成
analyzerは
analyzerが受信したパラメータはunicode文字列で、戻り値は文字列カットで、栗を挙げる
e.g.(
param = "Mary had a little lamb"
return = ["Mary", "had", "a", "little", "lamb"]
)
Whooshを使用している
やはり便利です.
最近、プロジェクトはWhooshのPythonが作成したインデックス検索モジュールを使います.中国語の資料が少なく、先輩のコードを見ても分からないことが多いことに気づきました.だから、自分で公式サイトのドキュメントに従って、自分の理解と公式サイトのよくない説明を書きました.
クイックハンド
いくつかのコアオブジェクト
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オブジェクトを作成するには、Field nameとField typeをキーワードでマッピングする必要があります.上記のように
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
次の点に注意してください.
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()
メソッドはQuiryオブジェクトを入力する必要があります.Quiryオブジェクトを直接構築したり、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=BM25F
これは検索の重みアルゴリズムであり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)
やはり便利です.