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

  • 17
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用 Whoosh 实现信息检索系统,可以按照以下步骤进行: 1. 安装 Whoosh:可以使用 pip 命令安装 Whoosh,如下所示: ``` pip install whoosh ``` 2. 创建索引:使用 Whoosh 可以创建索引,将需要检索的数据存储到索引中。下面是一个简单的示例: ```python from whoosh.index import create_in from whoosh.fields import * import os # 创建索引目录 if not os.path.exists("indexdir"): os.mkdir("indexdir") # 定义索引的schema my_schema = Schema(title=TEXT(stored=True), content=TEXT) # 创建索引 my_index = create_in("indexdir", my_schema) # 获取索引的writer对象 writer = my_index.writer() # 添加文档到索引 writer.add_document(title="Document 1", content="This is the content of document 1.") writer.add_document(title="Document 2", content="This is the content of document 2.") writer.add_document(title="Document 3", content="This is the content of document 3.") # 提交写入的文档 writer.commit() ``` 3. 查询匹配:使用 Whoosh 可以根据关键词进行查询匹配,下面是一个简单的示例: ```python from whoosh.qparser import QueryParser # 获取索引的searcher对象 searcher = my_index.searcher() # 定义查询解析器 query_parser = QueryParser("content", my_index.schema) # 解析查询语句 query = query_parser.parse("content:document") # 根据查询语句进行查询 results = searcher.search(query) # 输出匹配结果 for result in results: print(result["title"]) ``` 通过以上步骤,我们就可以使用 Whoosh 实现一个简单的信息检索系统。当然,在实际的应用中,还需要进行更多的优化和扩展,例如:分词、去重、排序等。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值