Whoosh由Matt Chaput創建,它一開始是一個為Houdini 3D動畫軟體包的線上文件提供簡單、快速的搜尋服務工具,之後便慢慢成為一個成熟的搜尋解決工具並已開源。
Whoosh純粹由Python編寫而成,是一個靈活的,方便的,輕量級的搜尋引擎工具,現在同時支援Python2、3,其優點如下:
Whoosh的官方介紹網站為:https://whoosh.readthedocs.io/en/latest/intro.html 。相較於ElasticSearch或Solr等成熟的搜尋引擎工具,Whoosh顯得更輕便,操作更簡單,可以考慮在小型的搜尋項目中使用。
對於熟悉ES的人來說,搜尋的兩個重要的面向為mapping和query,也就是索引的建構以及查詢,背後是複雜的索引儲存、 query解析以及排序演算法等。如果你有ES方面的經驗,那麼,對於Whoosh是十分容易上手的。
依照筆者的理解以及Whoosh的官方文檔,Whoosh的入門使用主要是index以及query。搜尋引擎的強大功能之一在於它能夠提供全文檢索,這依賴於排序演算法,例如BM25,也依賴我們怎麼儲存欄位。因此,index作為名詞時,是指字段的索引,index作為動詞時,是指建立字段的索引。而query會將我們需要查詢的語句,透過排序演算法,給出合理的搜尋結果。
關於Whoosh的使用,在官文文件中已經給出了詳細的說明,筆者在這裡只給出一個簡單的例子,來說明Whoosh如何能方便地提升我們的搜尋體驗。
本專案的範例資料為poem.csv,下圖為此資料集的前十行:
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中文網其他相關文章!