51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

手机号码,快捷登录

查看: 651|回复: 0
打印 上一主题 下一主题

[转贴] Whoosh:Python 的轻量级搜索工具

[复制链接]
  • TA的每日心情
    无聊
    前天 09:02
  • 签到天数: 975 天

    连续签到: 5 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2022-7-20 09:55:40 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    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,下图为该数据集的前十行:

    字段
       根据数据集的特征,我们创建四个字段(fields):title, dynasty, poet, content。创建的代码如下:
    1. # -*- coding: utf-8 -*-
    2.   import os
    3.   from whoosh.index import create_in
    4.   from whoosh.fields import *
    5.   from jieba.analyse import ChineseAnalyzer
    6.   import json
    7.   # 创建schema, stored为True表示能够被检索
    8.   schema = Schema(title=TEXT(stored=True, analyzer=ChineseAnalyzer()),
    9.                  dynasty=ID(stored=True),
    10.                  poet=ID(stored=True),
    11.                  content=TEXT(stored=True, analyzer=ChineseAnalyzer())
    12.                  )
    复制代码
    其中,ID只能为一个单元值,不能分割为若干个词,常用于文件路径、URL、日期、分类;
      TEXT文件的文本内容,建立文本的索引并存储,支持词汇搜索;Analyzer选择结巴中文分词器。
      创建索引文件
       接着,我们需要创建索引文件。我们利用程序先解析poem.csv文件,并将它转化为index,写入到indexdir目录下。Python代码如下:
    1. # 解析poem.csv文件
    2.   with open('poem.csv', 'r', encoding='utf-8') as f:
    3.      texts = [_.strip().split(',') for _ in f.readlines() if len(_.strip().split(',')) == 4]
    4.   # 存储schema信息至indexdir目录
    5.   indexdir = 'indexdir/'
    6.   if not os.path.exists(indexdir):
    7.      os.mkdir(indexdir)
    8.   ix = create_in(indexdir, schema)
    9.   # 按照schema定义信息,增加需要建立索引的文档
    10.   writer = ix.writer()
    11.   for i in range(1, len(texts)):
    12.      title, dynasty, poet, content = texts[i]
    13.      writer.add_document(title=title, dynasty=dynasty, poet=poet, content=content)
    14.   writer.commit()
    复制代码
    index创建成功后,会生成indexdir目录,里面含有上述poem.csv数据的各个字段的索引文件。
      查询
       index创建成功后,我们就利用进行查询。
       比如我们想要查询content中含有明月的诗句,可以输入以下代码:
    1. # 创建一个检索器
    2.   searcher = ix.searcher()
    3.   # 检索content中出现'明月'的文档
    4.   results = searcher.find("content", "明月")
    5.   print('一共发现%d份文档。' % len(results))
    6.   for i in range(min(10, len(results))):
    7.      print(json.dumps(results[i].fields(), ensure_ascii=False))
    复制代码
    输出结果如下:
    1. 一共发现44份文档。
    2.   前10份文档如下:
    3.   {"content": "床前明月光,疑是地上霜。举头望明月,低头思故乡。", "dynasty": "唐代", "poet": "李白 ", "title": "静夜思"}
    4.   {"content": "边草,边草,边草尽来兵老。山南山北雪晴,千里万里月明。明月,明月,胡笳一声愁绝。", "dynasty": "唐代", "poet": "戴叔伦 ", "title": "调笑令·边草"}
    5.   {"content": "独坐幽篁里,弹琴复长啸。深林人不知,明月来相照。", "dynasty": "唐代", "poet": "王维 ", "title": "竹里馆"}
    6.   {"content": "汉江明月照归人,万里秋风一叶身。休把客衣轻浣濯,此中犹有帝京尘。", "dynasty": "明代", "poet": "边贡 ", "title": "重赠吴国宾"}
    7.   {"content": "秦时明月汉时关,万里长征人未还。但使龙城飞将在,不教胡马度阴山。", "dynasty": "唐代", "poet": "王昌龄 ", "title": "出塞二首·其一"}
    8.   {"content": "京口瓜洲一水间,钟山只隔数重山。春风又绿江南岸,明月何时照我还?", "dynasty": "宋代", "poet": "王安石 ", "title": "泊船瓜洲"}
    9.   {"content": "四顾山光接水光,凭栏十里芰荷香。清风明月无人管,并作南楼一味凉。", "dynasty": "宋代", "poet": "黄庭坚 ", "title": "鄂州南楼书事"}
    10.   {"content": "青山隐隐水迢迢,秋尽江南草未凋。二十四桥明月夜,玉人何处教吹箫?", "dynasty": "唐代", "poet": "杜牧 ", "title": "寄扬州韩绰判官"}
    11.   {"content": "露气寒光集,微阳下楚丘。猿啼洞庭树,人在木兰舟。广泽生明月,苍山夹乱流。云中君不见,竟夕自悲秋。", "dynasty": "唐代", "poet": "马戴 ", "title": "楚江怀古三首·其一"}
    12.   {"content": "海上生明月,天涯共此时。情人怨遥夜,竟夕起相思。灭烛怜光满,披衣觉露滋。不堪盈手赠,
    复制代码






    本帖子中包含更多资源

    您需要 登录 才可以下载或查看,没有帐号?(注-册)加入51Testing

    x
    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /2 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-6-30 00:17 , Processed in 0.068666 second(s), 24 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表