首頁  >  文章  >  後端開發  >  Whoosh:Python 的輕量級搜尋工具

Whoosh:Python 的輕量級搜尋工具

PHPz
PHPz轉載
2023-04-14 21:07:011634瀏覽

Whoosh:Python 的輕量級搜尋工具

Whoosh簡介

 Whoosh由Matt Chaput創建,它一開始是一個為Houdini 3D動畫軟體包的線上文件提供簡單、快速的搜尋服務工具,之後便慢慢成為一個成熟的搜尋解決工具並已開源。

 Whoosh純粹由Python編寫而成,是一個靈活的,方便的,輕量級的搜尋引擎工具,現在同時支援Python2、3,其優點如下:

  • # Whoosh純粹由Python編寫而成,但很快,只需要Python環境即可,不需要編譯器;
  • 預設使用Okapi BM25F排序演算法,也支援其他排序演算法;
  • 相比於其他搜尋引擎,Whoosh會創建更小的index檔;
  • Whoosh中的index檔編碼必須是unicode;
  • Whoosh可以儲存任意的Python物件。

 Whoosh的官方介紹網站為:https://whoosh.readthedocs.io/en/latest/intro.html 。相較於ElasticSearch或Solr等成熟的搜尋引擎工具,Whoosh顯得更輕便,操作更簡單,可以考慮在小型的搜尋項目中使用。

Index & query

 對於熟悉ES的人來說,搜尋的兩個重要的面向為mapping和query,也就是索引的建構以及查詢,背後是複雜的索引儲存、 query解析以及排序演算法等。如果你有ES方面的經驗,那麼,對於Whoosh是十分容易上手的。

 依照筆者的理解以及Whoosh的官方文檔,Whoosh的入門使用主要是index以及query。搜尋引擎的強大功能之一在於它能夠提供全文檢索,這依賴於排序演算法,例如BM25,也依賴我們怎麼儲存欄位。因此,index作為名詞時,是指字段的索引,index作為動詞時,是指建立字段的索引。而query會將我們需要查詢的語句,透過排序演算法,給出合理的搜尋結果。

 關於Whoosh的使用,在官文文件中已經給出了詳細的說明,筆者在這裡只給出一個簡單的例子,來說明Whoosh如何能方便地提升我們的搜尋體驗。

範例程式碼

資料

 本專案的範例資料為poem.csv,下圖為此資料集的前十行:

Whoosh:Python 的輕量級搜尋工具

poem.csv

字段

 根據資料集的特徵,我們建立四個欄位(fields):title, dynasty, poet, content。建立的程式碼如下:

# -*- coding: utf-8 -*-
import os
from whoosh.index import create_in
from whoosh.fields import *
from jieba.analyse import ChineseAnalyzer
import json
# 创建schema, stored为True表示能够被检索
schema = Schema(title=TEXT(stored=True, analyzer=ChineseAnalyzer()),
 dynasty=ID(stored=True),
 poet=ID(stored=True),
 content=TEXT(stored=True, analyzer=ChineseAnalyzer())
 )

其中,ID只能為一個單元值,不能分割為若干個字,常用於檔案路徑、URL、日期、分類;

TEXT檔案的文本內容,建立文本的索引並存儲,支援詞彙搜尋;Analyzer選擇結巴中文分詞器。

建立索引檔

 接著,我們需要建立索引檔。我們利用程式先解析poem.csv文件,並將它轉化為index,寫入到indexdir目錄下。 Python程式碼如下:

# 解析poem.csv文件
with open('poem.csv', 'r', encoding='utf-8') as f:
 texts = [_.strip().split(',') for _ in f.readlines() if len(_.strip().split(',')) == 4]
# 存储schema信息至indexdir目录
indexdir = 'indexdir/'
if not os.path.exists(indexdir):
 os.mkdir(indexdir)
ix = create_in(indexdir, schema)
# 按照schema定义信息,增加需要建立索引的文档
writer = ix.writer()
for i in range(1, len(texts)):
 title, dynasty, poet, content = texts[i]
 writer.add_document(title=title, dynasty=dynasty, poet=poet, content=content)
writer.commit()

index建立成功後,會產生indexdir目錄,裡面有上述poem.csv資料的各個欄位的索引檔。

查詢

 index創建成功後,我們就利用進行查詢。

 例如我們想要查詢content中含有明月的詩句,可以輸入以下程式碼:

# 创建一个检索器
searcher = ix.searcher()
# 检索content中出现'明月'的文档
results = searcher.find("content", "明月")
print('一共发现%d份文档。' % len(results))
for i in range(min(10, len(results))):
 print(json.dumps(results[i].fields(), ensure_ascii=False))

輸出結果如下:

一共发现44份文档。
前10份文档如下:
{"content": "床前明月光,疑是地上霜。举头望明月,低头思故乡。", "dynasty": "唐代", "poet": "李白 ", "title": "静夜思"}
{"content": "边草,边草,边草尽来兵老。山南山北雪晴,千里万里月明。明月,明月,胡笳一声愁绝。", "dynasty": "唐代", "poet": "戴叔伦 ", "title": "调笑令·边草"}
{"content": "独坐幽篁里,弹琴复长啸。深林人不知,明月来相照。", "dynasty": "唐代", "poet": "王维 ", "title": "竹里馆"}
{"content": "汉江明月照归人,万里秋风一叶身。休把客衣轻浣濯,此中犹有帝京尘。", "dynasty": "明代", "poet": "边贡 ", "title": "重赠吴国宾"}
{"content": "秦时明月汉时关,万里长征人未还。但使龙城飞将在,不教胡马度阴山。", "dynasty": "唐代", "poet": "王昌龄 ", "title": "出塞二首·其一"}
{"content": "京口瓜洲一水间,钟山只隔数重山。春风又绿江南岸,明月何时照我还?", "dynasty": "宋代", "poet": "王安石 ", "title": "泊船瓜洲"}
{"content": "四顾山光接水光,凭栏十里芰荷香。清风明月无人管,并作南楼一味凉。", "dynasty": "宋代", "poet": "黄庭坚 ", "title": "鄂州南楼书事"}
{"content": "青山隐隐水迢迢,秋尽江南草未凋。二十四桥明月夜,玉人何处教吹箫?", "dynasty": "唐代", "poet": "杜牧 ", "title": "寄扬州韩绰判官"}
{"content": "露气寒光集,微阳下楚丘。猿啼洞庭树,人在木兰舟。广泽生明月,苍山夹乱流。云中君不见,竟夕自悲秋。", "dynasty": "唐代", "poet": "马戴 ", "title": "楚江怀古三首·其一"}
{"content": "海上生明月,天涯共此时。情人怨遥夜,竟夕起相思。灭烛怜光满,披衣觉露滋。不堪盈手赠,

以上是Whoosh:Python 的輕量級搜尋工具的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:51cto.com。如有侵權,請聯絡admin@php.cn刪除