当前位置: 首页 > 科技观察

Whoosh:Python的轻量级搜索工具

时间:2023-03-18 17:12:02 科技观察

Whoosh简介Whoosh由MattChaput创建。它最初是作为Houdini3D动画包在线文档的简单快速的搜索服务工具,后来慢慢成为成熟的搜索解决方案工具,并已开源。Whoosh完全是用Python编写的。它是一个灵活、方便、轻量级的搜索引擎工具。现在支持Python2和3。它的优点如下:Whoosh是纯Python写的,但是很快,只需要Python了。环境足够,不需要编译器;默认使用OkapiBM25F排序算法,也支持其他排序算法;与其他搜索引擎相比,Whoosh会创建更小的索引文件;Whoosh中的索引文件编码必须是unicode;Whoosh可以存储任意Python对象。Whoosh的官方介绍网站是:https://whoosh.readthedocs.io/en/latest/intro.html。与ElasticSearch或Solr等成熟的搜索引擎工具相比,Whoosh更轻巧,更易于操作,可以考虑在小型搜索项目中使用。索引&查询对于熟悉ES的人来说,搜索的两个重要方面是映射和查询,即索引构建和查询,其背后是复杂的索引存储、查询解析和排序算法。如果你有使用ES的经验,Whoosh是非常好用的。根据笔者的理解和Whoosh的官方文档,Whoosh的入门级用法主要是索引和查询。搜索引擎的强大功能之一就是可以提供全文搜索,这取决于排序算法,比如BM25,也取决于我们如何存储字段。因此,index作为名词时,指的是字段的索引,index作为动词时,指的是已建立字段的索引。查询会将我们需要查询的语句通过排序算法给出合理的搜索结果。关于Whoosh的使用,官方文档中已经给出了详细的说明。笔者这里只举一个简单的例子来说明Whoosh是如何方便的提升我们的搜索体验的。示例代码数据本项目的示例数据为poem.csv,下图为数据集的前十行:poem.csvfield根据数据集的特点,我们创建四个字段(fields):title,朝代,诗歌,内容。创建的代码如下:#-*-coding:utf-8-*-importosfromwhoosh.indeximportcreate_infromwhoosh.fieldsimport*fromjieba.analyseimportChineseAnalyzerimportjson#createschema,storedisTrue表示可以检索schema=Schema(title=TEXT(stored=True,analyzer=ChineseAnalyzer()),dynasty=ID(stored=True),poem=ID(stored=True),content=TEXT(stored=True,analyzer=ChineseAnalyzer()))其中,ID只能是一个单位值,不能分成几个词。它常用于文件路径、URL、日期和分类;TEXT文件的文本内容在文本中进行索引存储,支持词汇搜索;Analyzer选择stutteringChinesetokenizer。创建索引文件接下来,我们需要创建索引文件。我们先用程序解析poem.csv文件,转换成index,写入indexdir目录。Python代码如下:#解析poem.csv文件withopen('poem.csv','r',encoding='utf-8')asf:texts=[_.strip().split(',')for_inf.readlines()iflen(_.strip().split(','))==4]#将模式信息存储到indexdir目录indexdir='indexdir/'ifnotos.path.exists(indexdir):os.mkdir(indexdir)ix=create_in(indexdir,schema)#根据schema定义信息,添加需要索引的文档writer=ix.writer()foriinrange(1,len(texts)):title,dynasty,poem,content=texts[i]writer.add_document(title=title,dynasty=dynasty,poet=poet,content=content)writer.commit()创建索引成功后,一个将生成indexdir目录,其中包含上述poem.csv数据各个字段的索引文件。查询索引创建成功后,我们使用它进行查询。比如我们要查询内容中包含明月的经文,可以输入如下代码:#创建一个搜索器searcher=ix.searcher()#搜索内容中包含'明月'的文档results=searcher.find("content","明月")print('共找到%d个文档'%len(results))foriinrange(min(10,len(results))):print(json.dumps(results[i].fields(),ensure_ascii=False))输出结果如下:共找到44个文档。前10个文件如下:{"content":"床前月光疑是地上霜,抬头看月,低头看故乡。","dynasty":"TangDynamic","poet":"LiBai","title":《静夜思》}{"content":"依草,草草,草枯到老士兵。南山北雪清,万里月明。明月,明月,胡佳发出一声悲痛的叫声。","dynasty":"TangDynamic","poet":"戴叔伦","title":《嘲令·编草》}{"content":"独坐幽竹,又弹琴歌唱.深林人不知,明月来照。","dynasty":"TangDynasty","poet":"WangWei","title":"竹离阁"}{"content":"汉江明月照人,秋风吹千里万里留一身。休轻洗客衣,里面还有景琛帝君。","dynasty":"MingDynasty","poet":"卞公","title":"再赠吴国斌"}{"content":"秦始皇明月汉史关长征还没有回来。却让龙城的飞将留下,也不教呼玛去阴山。","dynasty":"TangDynasty","poet":"WangChangling","title":"两首出塞诗"}{"content":"京口瓜州一水峡,与中山仅相距数里重山。春风绿江南岸,明月几日照我?","朝代":"宋代","诗人":"王安石","题名":《船瓜洲》}{"content":"山水环抱,十里倚栏赏荷香。清风明月无人问,南楼一味凉。","朝代":"宋代","诗人":"黄庭坚","题名":《鄂州南楼书事》}{"content":"青山隐水远,江南草未枯。二十四桥月夜,玉人何处教笛?","dynasty":"TangDyst","poet":"DuMu","title":《评扬州汉绰》}{"content":"露气寒光聚,楚秋脚下艳阳高照。猿对洞庭树歌,人在玉兰船。明月生于广泽,苍山环抱激流。云中不见君,夜愁秋。","dynasty":"TangDynasty","poet":"MaDai","title":"楚江乡三首·上"}{"content":"明月生于大海,世界的尽头分享这一刻。情人怨夜,相思夜起。烛灭时,光满怜惜,衣裳感露。难以忍受的慷慨,