Whoosh是一個Python的開源搜尋引擎,它提供了在Python中建立,索引和搜尋文本的能力。Whoosh具有高度的可定制性,可以滿足各種搜尋需求,包括全文搜尋,模糊搜尋,範圍搜尋等。Whoosh支援多種存儲格式,如SQLite,MySQL,PostgreSQL和MongoDB等。此外,Whoosh還提供了對中文文本的索引和搜尋支援。
whoosh安裝
whoosh預設使用英文分詞,使用中文分詞需要額外安裝jieba。
pip install whoosh
# 中文分詞時需要
pip install jieba
導入whoosh
from whoosh.fields import *
from whoosh.qparser import QueryParser
from whoosh.index import create_in
from whoosh.index import open_dir
from whoosh.sorting import FieldFacet
from jieba.analyse import ChineseAnalyzer
import os
定義索引字段
whoosh預設使用英文分詞,使用中文分詞需要導入jieba進行中文分詞。
# 導入中文分詞工具
analyser = ChineseAnalyzer()
# 建立索引結構
'''
建立了title和content兩個索引字段,TEXT為正文文本字段,stored=True表示将存儲該字段資料用于搜尋結果的傳回,analyzer=analyser表示使用中文分詞,
根據需要可以添加多個字段。
'''
schema = Schema(title=TEXT(stored=True, analyzer=analyser),
content=TEXT(stored=True, analyzer=analyser),)
當建立 Schema 對象時,使用關鍵字參數将字段名映射到字段類型。字段清單及其類型定義了要索引的内容和可搜尋的内容
常用字段解釋
whoosh.fields.ID
此類型隻将字段的整個值作為單個單元進行索引(并可選地存儲)(也就是說,它不會将字段分解為單個單詞)。這對于檔案路徑、URL、日期、類别等字段很有用。
whoosh.fields.STORED
此字段與文檔一起存儲,但未編入索引。此字段類型沒有索引且不可搜尋。這對于要在搜尋結果中顯示給使用者的文檔資訊很有用。
whoosh.fields.KEYWORD
此類型是為空格或逗号分隔的關鍵字設計的。此類型是可索引和搜尋的(并且可以選擇存儲)。為了節省空間,它不支援短語搜尋。
whoosh.fields.TEXT
此類型用于正文文本。它索引(并可選地存儲)文本并存儲術語位置,以允許短語搜尋。
whoosh.fields.NUMERIC
此類型用于數字。您可以存儲整數或浮點數。
whoosh.fields.BOOLEAN
此類型用于布爾值。
whoosh.fields.DATETIME
此類型用于時間類型。
建立索引
索引隻需建立一次,
# 索引路徑,根據實際需要進行修改。
index_path = r"C:\index"
# 索引路徑不存在則建立,存在則調用open_dir方法打開索引
if not os.path.exists(index_path):
os.mkdir(index_path)
# 使用create_in方法建立索引,index_path為索引路徑,schema為前面定義的索引字段,indexname為索引名稱(根據需要進行修改)
ix = create_in(index_path, schema=schema, indexname='indexname')
else:
ix = open_dir(index_path, indexname='indexname')
索引中添加資料
writer = ix.writer()
# 使用add_document向索引内添加内容
writer.add_document(title='使用手冊', content='XXX使用手冊')
# 送出
writer.commit()
搜尋
索引中添加完資料之後通過 ix.searcher()方法進行搜尋。
with ix.searcher() as searcher:
# 單關鍵詞搜尋
# parser = QueryParser("title", ix.schema).parse("手冊")
# 多關鍵詞同時搜尋
parser = MultifieldParser(["title", 'content'], ix.schema).parse("手冊")
# 對結果進行排序
facet = FieldFacet("title", reverse=True)
# limit為搜尋結果的限制,預設為10,None為不限制。sortedby為排序規則
results = searcher.search(parser, limit=None, sortedby=facet, terms=True)
# 列印搜尋結果
for i in results:
# title關鍵詞高亮
print(i.highlights('title'))
# content關鍵詞高亮
print(i.highlights('content'))
# 所有字段資訊
print(i.fields())
其他操作
# 删除索引
ix.delete_by_term('title','使用手冊') # 删除title為’使用手冊‘的索引
# 清空索引
方法1:先删除索引檔案檔案夾或者索引檔案後,調用create_in重建即可。
方法2:直接調用create_in方法進行重建。
重新定義關鍵詞高亮
whoosh自帶的關鍵詞高亮highlights()方法,在個别情況下比對高亮關鍵詞之後丢失部分内容。
例如下圖,搜尋【天氣】時可以檢索出1條内容,調用高亮方法後傳回的結果前面丢失了一個數字【7】,在whoosh中未找到解決方法。
目前單獨寫了一個python
目前解決辦法:
單獨定義一個關鍵詞高亮的方法替代這一部分。
import re
def highlight_keywords(text, keywords):
# 定義高亮樣式,根據需要進行修改,目前沿用的whoos預設的高亮樣式
style = '<b class="match term0">'
# 将關鍵詞轉換為正規表達式,并使用re.escape處理特殊字元
pattern = "|".join(map(re.escape, keywords))
# 使用正規表達式比對關鍵詞,并替換為高亮樣式
result = re.sub(pattern, lambda match: style + match.group(0) + "</b>", text)
return result
應用到whoosh搜尋中
修改此部分代碼,15行和21行代碼是重點。
with ix.searcher() as searcher:
# 單關鍵詞搜尋
# parser = QueryParser("title", ix.schema).parse("手冊")
# 多關鍵詞同時搜尋
parser = MultifieldParser(["title", 'content'], ix.schema).parse("手冊")
# 對結果進行排序
facet = FieldFacet("title", reverse=True)
# limit為搜尋結果的限制,預設為10,None為不限制。sortedby為排序規則
results = searcher.search(parser, limit=None, sortedby=facet, terms=True)
# 通過query_terms()方法提取分詞結果,并轉為清單形式。
keywords = [i[1].decode('utf-8') for i in list(results.query_terms())]
# 列印搜尋結果
for i in results:
# 調用highlight_keywords()方法,将标題和關鍵詞清單傳入
print(highlight_keywords(i['title'], keywords))
# 所有字段資訊
print(i.fields())
結果如下:
複制所有代碼到py檔案可直接使用。