Django之使用haystack+whoosh实现搜索功能
为了实现项目中的搜索功能,我们使用的是全文检索框架haystack+搜索引擎whoosh+中文分词包jieba
安装和配置
安装所需包
pip install django-haystack pip install whoosh pip install jieba
去settings文件注册haystack应用
INSTALLED_APPS = [ 'haystack', # 注册全文检索框架 ]
在settings文件中配置全文检索框架
# 全文检索框架的配置 HAYSTACK_CONNECTIONS = { 'default': { # 使用whoosh引擎 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine', # 索引文件路径 'PATH': os.path.join(BASE_DIR, 'whoosh_index'), } } # 当添加、修改、删除数据时,自动生成索引 HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
索引文件的生成
要生成索引文件,首先你要配置,对哪些内容进行索引,比如商品名称,简介和详情;为了配置对数据库指定内容进行索引,我们要做如下步骤:
配置search_indexes.py文件
因为在django中数据库一般都是通过ORM生成的,首先我们在要在数据表对应的应用中创建一个 search_indexes.py 文件,例如,我现在要检索商品对应的表就是GoodsSKU表,而表是在goods应用下的,所以我在goods应用下新建 search_indexes.py 文件,截图如下:
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <title>Title</title> </head> <body> 搜索的关键字:{{ query }}<br/> 当前页的Page对象:{{ page }}<br/> <ul> {% for item in page %} <li>{{ item.object }}</li> {% endfor %} </ul> 分页paginator对象:{{ paginator }}<br/> </body> </html>templates/indexes/search.html 注意,位置和文件名都是固定的,并且这只是测试文件,后面使用全文检索时记得不能使用search.html,改成其他名字。
数据+search.html返回渲染后页面
当haystack全文检索后会返回数据,现在我们需要一个页面来接收这些数据,并且在页面渲染后返回这个页面给用户观看,渲染并返回页面的工作haystack已经帮我们做了,那么我们现在只需要准备一个页面容纳数据即可。
在templates文件夹下的indexes文件夹下新建一个search.html,注意路径和文件名是固定的,如下图
<div class="breadcrumb"> <a href="#">{{ query }}</a> <span>></span> <a href="#">搜索结果如下:</a> </div> <div class="main_wrap clearfix"> <ul class="goods_type_list clearfix"> {% for item in page %} <li> <a href="{% url 'goods:detail' item.object.id %}"><img src="{{ item.object.image.url }}"></a> <h4><a href="{% url 'goods:detail' item.object.id %}">{{ item.object.name }}</a></h4> <div class="operate"> <span class="prize">¥{{ item.object.price }}</span> <span class="unit">{{ item.object.price}}/{{ item.object.unite }}</span> <a href="#" class="add_goods" title="加入购物车"></a> </div> </li> {% endfor %} </ul> <div class="pagenation"> {% if page.has_previous %} <a href="/search?q={{ query }}&page={{ page.previous_page_number }}"><上一页</a> {% endif %} {% for pindex in paginator.page_range %} {% if pindex == page.number %} <a href="/search?q={{ query }}&page={{ pindex }}" class="active">{{ pindex }}</a> {% else %} <a href="/search?q={{ query }}&page={{ pindex }}">{{ pindex }}</a> {% endif %} {% endfor %} {% if page.has_next %} <a href="/search?q={{ query }}&page={{ page.next_page_number }}">下一页></a> {% endif %} </div> </div>search.html 至此,我们可以在页面上搜索一下内容,应该是能成功的,但也有可能不会返回任何数据就算name就是你搜索的内容,这是因为我们现在使用的主要还是为英语服务的分词包,接下来我们要配置使用中文分词包了。
使用中文分词包jieba
在前面的配置中我们已经安装了jieba;
创建 ChineseAnalyzer.py 文件
进入虚拟环境下的 Lib\site-packages\haystack\backends 目录下新建 ChineseAnalyzer.py 文件
目录如下图
import jieba from whoosh.analysis import Tokenizer, Token class ChineseTokenizer(Tokenizer): def __call__(self, value, positions=False, chars=False, keeporiginal=False, removestops=True, start_pos=0, start_char=0, mode='', **kwargs): t = Token(positions, chars, removestops=removestops, mode=mode, **kwargs) seglist = jieba.cut(value, cut_all=True) for w in seglist: t.original = t.text = w t.boost = 1.0 if positions: t.pos = start_pos + value.find(w) if chars: t.startchar = start_char + value.find(w) t.endchar = start_char + value.find(w) + len(w) yield t def ChineseAnalyzer(): return ChineseTokenizer()ChineseAnalyzer.py
编写haystack可使用的 whoosh_cn_backend.py 文件
直接在 虚拟环境下的 Lib\site-packages\haystack\backends 目录下复制一份 whoosh_backend.py 文件 并且重命名复制文件为 whoosh_cn_backend.py;
在 whoosh_cn_backend.py 中导入我们编写的 ChineseAnalyzer 类
from .ChineseAnalyzer import ChineseAnalyzer
更改haystack使用的分词包为 jieba 编写的中文分词类,大概在第160行左右
# schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=StemmingAnalyzer(), field_boost=field_class.boost, sortable=True) schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(), field_boost=field_class.boost, sortable=True)
配置whoosh引擎使用 whoosh_cn_backend.py
在settings文件中更改原来的配置如下
# 全文检索框架的配置 HAYSTACK_CONNECTIONS = { 'default': { # 使用whoosh引擎 # 'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine', 'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine', # 索引文件路径 'PATH': os.path.join(BASE_DIR, 'whoosh_index'), } } # 当添加、修改、删除数据时,自动生成索引 HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
重新生成索引文件
python manage.py rebuild_index
至此,就可以放心的使用搜索功能了,如图,搜索成功的显示页面
可以通过如下配置控制每个分页显示的搜索出来对象的数目
# 指定搜索结果每页显示的条数 HAYSTACK_SEARCH_RESULTS_PER_PAGE = 1
- django使用haystack对接Elasticsearch实现商品搜索
- Django中使用JS通过DataTable实现表格前端分页,每页显示页数,搜索等功能
- Django开发个人博客网站——19、通过Django Haystack实现搜索功能(上)
- 使用haystack实现django全文检索搜索引擎功能
- Django中使用JS通过DataTable实现表格前端分页,每页显示页数,搜索等功能
- django使用haystack调用Elasticsearch实现索引搜索
- Python中使用haystack实现django全文检索搜索引擎功能
- django中使用whoosh+haystack+jieba进行中文模糊搜索
- 使用python代码实现三叉搜索树高效率”自动输入提示”功能
- 实现Django的全文检索功能(一):选择Whoosh全文检索引擎
- 使用Bootrap和Vue实现仿百度搜索功能
- 实现Django的全文检索功能(三):进一步学习Haystack
- Python Django使用forms来实现评论功能
- 使用Django实现分页器功能
- 实现Django的全文检索功能(三):进一步学习Haystack
- Django使用Ajax实现页面无刷新评论回复功能
- 使用localStorage实现历史记录搜索功能
- 使用bootstrap-select插件来实现下拉菜单搜索匹配功能
- python使用正则表达式的search()函数实现指定位置搜索功能
- 使用C语言实现模糊搜索功能