• python全文检索库:whoosh


    引言

    Whoosh 是什么?

    Whoosh 是一个用纯 Python 编写的全文搜索库,设计初衷是为 Python 应用提供快速、灵活和高效的搜索功能。与其他搜索引擎不同,Whoosh 完全基于python实现,不依赖于外部服务或平台,因此非常适合嵌入到各种 Python 项目中。

    Whoosh 的应用场景

    • 日志文件分析:Whoosh 可以用来搜索和分析日志文件,帮助系统管理员快速定位问题或异常。
    • 搜索引擎:Whoosh 可以用来构建简单的搜索引擎,帮助用户在大量文档中快速找到所需信息。
    • 内容管理系统:在内容管理系统中,Whoosh 可以用来索引文章、博客帖子或其他内容,以便用户能够搜索相关内容。

    为什么选择 Whoosh?

    • 纯 Python 实现:无需其他依赖,易于安装和使用。
    • 灵活性:可以根据需求定制索引和搜索行为。
    • 易于集成:适用于各种 Python 项目和框架。
    • 高效性:尽管是纯 Python 实现,但性能表现优异,足以满足大多数应用需求。

    安装

    环境要求

    Whoosh 兼容 Python 3.x,并且没有其他特定的系统要求。

    安装 Whoosh

    可以通过 pip 安装 Whoosh:

    pip install Whoosh
    

    创建和管理索引

    定义 Schema并建立索引目录

    Schema 定义了索引的结构,包括字段名称和类型。以下是一个简单的 Schema 定义:

    from whoosh.index import create_in
    from whoosh.fields import Schema, TEXT, ID
    
    schema = Schema(title=TEXT(stored=True), path=ID(stored=True), content=TEXT)
    index_dir='index'
    ix = create_in(index_dir, schema)
    

    我的理解就是相当于数据库的建表操作
    其中stored用于指明是否存储该项的具体值

    • 如果为True可以再搜索结果中直接访问到这个字段
    • 如果为False的话就只能进行搜索,但是在结果中是无法直接访问具体内容的。

    原因是倒排索引本身只会建立词元到记录之间的映射关系,并不会保存记录本身。要显示保存记录才能在搜索结果中访问

    添加文档到索引

    添加文档到索引非常简单,只需使用 IndexWriter 对象:

    from whoosh.index import open_dir
    
    ix = open_dir(index_dir)
    writer = ix.writer()
    
    writer.add_document(title=u"My Document", path=u"/a", content=u"This is the content of my document.")
    writer.commit()
    

    打开索引,然后获取writer,使用writer对象的add_document方法添加记录,最后使用commit方法确认提交。
    whoosh会自动的进行词法分析并据此建立词元到记录之间的索引关系。

    更新和删除文档

    更新文档与添加文档类似,可以先删除旧文档,再添加新文档:

    # 删除文档
    writer.delete_by_term('path', u'/a')
    
    # 添加更新后的文档
    writer.add_document(title=u"Updated Document", path=u"/a", content=u"Updated content.")
    writer.commit()
    

    搜索功能

    基本搜索语法

    使用 Searcher 对象进行搜索,实现了上下文管理器:

    from whoosh.qparser import QueryParser
    
    with ix.searcher() as searcher:
    	# 这一句分成两部分理解:
    	# 1、根据schema和查询字段生成一个查询解析器
    	# 2、使用查询解析器解析查询语句并生成查询对象
    	
        query = QueryParser("content", ix.schema).parse(u"document")
        
        results = searcher.search(query)
        for result in results:
            print(result['title'])
    

    这种方法只能在单个字段上查询,比如根据时间查询,根据作者查询等等

    高级搜索功能

    Whoosh 支持多种高级搜索功能,如布尔查询、通配符查询和范围查询:

    from whoosh.qparser import MultifieldParser
    
    query = MultifieldParser(["title", "content"], ix.schema).parse(u"title:document AND content:updated")
    results = searcher.search(query)
    

    ps:就不细说了,我做日志分析也用不到这么多

    处理搜索结果

    搜索结果包含多个匹配的文档,可以通过遍历 results 对象来处理每个结果:

    for result in results:
        print(result['title'], result['path'])
    

    分析器和过滤器

    使用

    Whoosh 提供了多种分析器和过滤器,可以根据需要进行定制:

    from whoosh.analysis import StemmingAnalyzer
    
    analyzer = StemmingAnalyzer()
    schema = Schema(title=TEXT(stored=True, analyzer=analyzer), content=TEXT(analyzer=analyzer))
    

    注意

    就是在划分词元的时候用什么分词器来划分,划分会影响索引的效果
    比如:

    • 有一个文档的内容是:我爱中国
    • 分词器1划分:[我,爱,中国]
    • 分词器2划分:[我爱,中国]
      那么此时我们搜索,基于分词器2构建的索引是检索不到的

    如果使用分词器2,搜索词“我”并没有被单独划分出来,而是与“爱”一起作为一个词元“我爱”。在这种情况下,如果用户搜索“我”,基于分词器2构建的索引将无法检索到包含“我爱中国”的文档,因为索引中没有单独的词元“我”。

    非结构化日志分析思路

    背景

    我需要对服务器每天产生的大量日志文件进行分析,检索出持续时间过长的请求(一次请求会产生多条日志,并且分布在各处,由id标识)和sql查询,并且还要定位出所有的系统出错。

    思路

    1. 建立索引,字段包括:时间,id,内容等
    2. 通过正则表达式提取每条日志的信息插入到索引中,同时用集合记录请求id
    3. 根据记录的请求id进行查询,直接查出该请求的全部日志,然后计算持续时间等数据
    4. 根据持续时间维护指定容量的最小堆(我们只需要查找耗时最长的n次请求,并且如果直接先计算全部请求的数据然后进行排序会消耗大量的内存)
    5. sql同理
    6. 错误就更简单了,先分析每种出错类型的查询词,然后直接在指定字段检索即可。例如:
      • “系统内部错误”
      • “外部接口错误”

    2024/8/6

  • 相关阅读:
    After Effects动态图形和数据可视化
    lwIP 开发指南(下)
    Java | UDP协议
    【学习笔记69】函数的柯里化
    通信算法之七十八:无人机反制—精华总结
    【程序大侠传】异步架构应用回调数据接收接口偶发NPE
    前端JS算法--插入排序
    【笔记】centos7 python2.7.5安装paramiko
    【微信小程序】一文带你搞懂小程序的页面配置和网络数据请求
    【秋招基础知识】轻量化:MobileNetv123和ShuffleNet
  • 原文地址:https://blog.csdn.net/longforone/article/details/140953377