whoosh mysql_使用Whoosh构建自己的搜索引擎
whoosh 是一个纯python实现的全文搜索引擎,它小巧轻便,安装简单,设计上参考了 Lucene ,性能上虽有欠缺,但贵在方便,无需复杂安装,对于构建小型网站的搜索引擎来说,是一个不错的选择。
1. 快速入门
whoosh 可以使用pip进行安装
pip install whoosh
现在通过官网的例子,快速体验
from whoosh.index import create_in
from whoosh.fields import *
# 构建索引
schema = Schema(title=TEXT(stored=True), path=ID(stored=True), content=TEXT)
ix = create_in("indexdir", schema)
writer = ix.writer()
writer.add_document(title=u"First document", path=u"/a",content=u"This is the first document we've added!")
writer.add_document(title=u"Second document", path=u"/b", content=u"The second one is even more interesting!")
writer.commit()
# 搜索
from whoosh.qparser import QueryParser
with ix.searcher() as searcher:
query = QueryParser("content", ix.schema).parse("first")
results = searcher.search(query)
print(results[0])
程序最终输出结果为
官网上的例子,我没有做任何修改,只是添加了两行注释。整个程序分为两部分,第一部分是构建索引的过程,第二部分是搜索的过程。
2. 构建索引
2.1 倒排索引
搜索引擎的关键技术是建立倒排索引,倒排索引记录了哪些文档中包含了某个单词,比如 “酷python” 这个词出现在了你正在看的这篇文章中,假设这篇文章的编号是111, 那么索引中就会记录一条 酷python:111的记录。当你搜索 酷python 这个词的时候,搜索引擎从倒排索引中找到 酷python所对应的文档,如果有多个,搜索引擎则计算文档与搜索词的相关性,并根据相关性进行排序返回给你结果。
2.2 分词
我们在搜索时,所搜索的关键词可能是一个句子,文档里那么多内容,但索引只记录词与文档编号之间的映射关系,因此,不论是构建索引还是根据关键词进行搜索,都得进行分词。对于英语文档,分词是一件简单的事情,因为英语的句子是由若干个单次组成的。而中文的分词则相对复杂,因为我们的词是由单个汉字组成的,而词与词之间是没有空格这种明显的分界的,具体哪几个汉字组成一个词,要看所处的语境,比如 “ 军任命了一名中将 ”, 这里中将就是一个词,但在句子“ 产量三年中将增长两倍 ”, 中将 就不再是一个词。
但你大可不必担心,因为现在的中文分词技术已经非常成熟了,开源库jieba可以满足你绝大部分需求。
2.3 索引模式
现在要为100篇文章构建索引,一篇文章的信息可能包括 文章标题,内容,作者,在构建索引的时候,你需要定义索引模式,就如同定义一张mysql里的表,你需要指出需要存储哪些字段,以及这些字段的类型
from whoosh.fields import TEXT, SchemaClass
from jieba.analyse import ChineseAnalyzer
analyzer = ChineseAnalyzer()
class ArticleSchema(SchemaClass):
title = TEXT(stored=True, analyzer=analyzer)
content = TEXT(stored=True, analyzer=analyzer)
author = TEXT(stored=True, analyzer=analyzer)
与官网中的例子不同,我通过继承SchemaClass 来实现一个新的类,以此定义索引模式。而且我设置了analyzer 为ChineseAnalyzer, 这样whoosh就可以支持中文索引了,analyzer会对文档中的中文进行分词。
2.4 添加文档
schema = ArticleSchema()
ix = create_in("indexdir", schema, indexname='article_index')
writer = ix.writer()
writer.add_document(title="登鹳雀楼", author="王之涣",content="白日依山尽,黄河入海流,欲穷千里目,更上一层楼")
writer.add_document(title="登高", author="杜甫", content="风急天高猿啸哀,渚清沙白鸟飞回")
writer.add_document(title="胡乱写的", author="黄河恋", content="展示效果")
writer.commit()
create_in 会创建一个名为indexdir 的文件夹,添加文档时,一定要根据你所定义的索引模式进行添加,这样就创建好了索引,添加文档的过程,就如同向mysql的表里写入数据。
3. 搜索
搜索的过程,需要使用open_dir函数打开索引文件,创建Searcher 对象
from whoosh.qparser import QueryParser
from whoosh.index import open_dir
ix = open_dir("indexdir", indexname='article_index')
with ix.searcher() as searcher:
query = QueryParser("content", ix.schema).parse("黄河")
results = searcher.search(query)
print(results[0])
程序输出结果
3.1 高亮显示
我们在百度搜索引擎搜索关键词所得到的结果,那些与关键词匹配的部分会被高亮显示,这样方便用户查看内容,这个功能,whoosh同样支持
with ix.searcher() as searcher:
query = QueryParser("content", ix.schema).parse("黄河")
results = searcher.search(query)
data = results[0]
text = data.highlights("content")
print(text)
程序输出结果为
白日依山尽,黄河入海流,欲穷千里目
在html文件中,你可以自己来定义match 和 term0 的样式。
3.2 多个字段同时搜索
对多个字段同时搜索,需要使用MultifieldParser
from whoosh.qparser import QueryParser, MultifieldParser
from whoosh.index import open_dir
ix = open_dir("indexdir", indexname='article_index')
with ix.searcher() as searcher:
query = MultifieldParser(["content", 'author'], ix.schema).parse("黄河")
results = searcher.search(query)
for data in results:
print(data)
content中有黄河,或者author有黄河的文档,都可以被搜索出来,程序输出结果
3.3 多个关键词同时搜索
如果你所搜索的内容并不仅仅是一个关键词,而是多个,或者你搜索的是一个句子,搜索引擎会把你的句子进行分词,得到若干个词,这些词作为条件进行搜索,只有被搜索的字段同时满足这些关键词时,才能得到搜索结果,比如下面的搜索
query = MultifieldParser(["content", 'author'], ix.schema).parse("黄河 杜甫")
这个搜索条件不会得到任何结果,原因在于搜索条件等价于
((content:黄河 OR author:黄河) AND (content:杜甫 OR author:杜甫))
被搜索的字段中,比如同时包含黄河与杜甫。如果你希望这些关键词之间是或的关系,那么需要你自己来构建搜索条件
from whoosh.qparser import QueryParser, MultifieldParser
from whoosh.index import open_dir
from whoosh.query import compound, Term
ix = open_dir("indexdir", indexname='article_index')
with ix.searcher() as searcher:
author_query = [Term('author', '黄河'), Term('author', '杜甫')]
content_query = [Term('content', '黄河'), Term('content', '杜甫')]
query = compound.Or([compound.Or(author_query), compound.Or(content_query)])
print(query)
results = searcher.search(query)
for data in results:
print(data)
三个文档都会被搜索到, 如果你搜索的是一个句子,那么你可以使用analyzer 对整个句子进行分词,然后构造搜索条件,我所说的analyzer就是 analyzer = ChineseAnalyzer() 语句创建的对象。
3.4 分页搜索
如果搜索结果太多,那么你需要分页查询
results = searcher.search_page(query, 1) # 搜索第1页,默认每页10个结果
print(results.total) # 搜索到的文档总量,帮助你进行分页
你获取的是第一页的搜索结果,但results.total 会告诉你搜索结果一共有多少条,这样,你就知道该搜索多少页的数据了。
whoosh mysql_使用Whoosh构建自己的搜索引擎相关推荐
- 利用Xapian构建自己的搜索引擎:检索
经过前面几篇的介绍,如果再参考一下Omega的话,估计应该可以顺利创建database和往database里添加document了.有了数据,下一步关心的当然是怎样将它们查出来,在一个IR系统(不单止 ...
- 使用Whoosh构建自己的搜索引擎、whoosh和jieba实现中文全文检索
whoosh 是一个纯python实现的全文搜索引擎,它小巧轻便,安装简单,设计上参考了 Lucene ,性能上虽有欠缺,但贵在方便,无需复杂安装,对于构建小型网站的搜索引擎来说,是一个不错的选择.1 ...
- java搜索引擎mysql_用Java MySQL PHP轻松构建跨平台的搜索引擎
此搜索引擎适于在一个中等规模的局域网中使用,由于找到的网页存在数据库中,不仅可以索静态的HTML页面,可以搜索php.asp等动态页面.对于一个拥有5万个网页的系统(使用PII-400作为服务器),搜 ...
- whoosh mysql_使用WhooshAlchemy报错'function' object has no attribute 'config'
我想用WhooshAlchemy做全文搜索,但是用的时候报错: 我的config.py: import os from app import basedir CSRF_ENABLED = True S ...
- 如何成功构建大规模 Web 搜索引擎架构?
Web搜索引擎十分复杂,我们的产品是一个分布式系统,在性能和延迟方面有非常苛刻的要求.除此之外,这个系统的运营也非常昂贵,需要大量人力,当然也需要大量金钱. 这篇文章将探讨我们使用的一些技术栈,以及我 ...
- 假如苹果构建了一个搜索引擎
作者 | Jean-Louis Gassée 译者 | 弯月 责编 | 欧阳姝黎 出品 | CSDN(ID:CSDNnews) 微软和许多其他的软件公司都构建了自己的搜索引擎,那么我们来畅想一 ...
- 使用Keras构建深度图像搜索引擎
动机 想象一下,如果有数十万到数百万张图像的数据集,却没有描述每张图像内容的元数据.我们如何建立一个系统,能够找到这些图像的子集来更好地回答用户的搜索查询? 我们基本上需要的是一个搜索引擎,它能够根据 ...
- python 全文检索 whoosh flask_基于whoosh的flask全文搜索插件flask-msearch
flask 的全文搜索插件很少,有个Flask-WhooshAlchemy,最近发现个flask-msearch,使用了下感觉不错. 安装flask-msearch pip install flask ...
- 如何构建一个新闻搜索引擎
首先展示一下项目效果图: 前言: 本项目会指导大家从零开始开始构建一个针对于新浪新闻的搜索引擎.首先我们明确一下我们的目标和所需要做的工作: 目标: 构建一个搜索引擎 所需工作: 准备数据 一个搜索引 ...
最新文章
- AD rodc扩展报错
- linux install命令文件夹,详解Linux系统中的install命令的用法
- python编程语言的优缺点-程序员千万不要入错行!常见的AI编程语言优缺点比较...
- python100行代码-怎样写贪吃蛇小游戏?用100行python代码轻松解决!
- i18n and L10n
- python向数据库写入数据_如何用Python向Mysql中插入数据
- 浅析ASP.NET应用ViewState技术
- 微信小程序开发的入门基础知识点
- Linux 命令出现号(大于号)如何退出
- 二维数组求和 团队开发
- javascript 西瓜一期 13 十六进制的数数方式与进位
- Spring Boot加入websocket后,单元测试报错(javax.websocket.server.ServerContainer not available)
- 数据驱动创新 融合引领变革 2017中国工业大数据大会·钱塘峰会今日在杭州国际博览中心顺利举行...
- js 倒计时 php,2种简单的js倒计时实现方法
- kvm初体验之八:调整vm的vcpu, memory, disk大小
- java后端简历项目经历_java后台开发个人简历怎么写
- 记录小新pro13 Intel版(S540-13IML)安装hackintosh的一些要点
- 201万年薪,华为天才少年路径可以复制吗
- 华为云从入门到实战 | 云速建站服务与企业主机安全服务
- 指数型基金基本信息 API 数据接口
热门文章
- linux下安装vsftpd vsftpd.conf配置 访问ftp时候输入正确的用户名密码还是一直弹出提示让你输入的原因
- win10开机慢怎么解决_win10系统电脑开机慢的应对办法
- python3.6遇到Unicode编码字符串比较问题:\u672a\u4f7f\u7528与同样内容的变量比较总是false[已解决]
- 一个Java程序员的腾讯面试心得
- AutoCAD .Net 使用 DrawJig 来动态地移动、旋转、缩放多个图元
- java 润乾报表_最理想的JAVA报表工具
- VUE 移动端处理input光标定位在最后的问题(简单版)
- K3s部署rancher
- Unity3d——打飞碟游戏(终极版)
- html兼容的图片是什么意思,人的兼容性是什么意思