django中haystack+whoosh+jieba实现网站的全局搜索功能

一提起数据库关键搜索,相信大家都会想起like语句,django中也可以使用orm的contains进行查询,这种查询是非常耗时间的,对于小量数量还可以,但随着数据的增多,查询速度会急剧下降,因此网站中使用这种方式是非常不合理的。基于这种情况,许多全文搜索框架应运而生。
本来打算使用haystack+elasticsearch实现全局搜索,但windows的系统环境问题和windows版的docker让我几近崩溃,不得不放弃,我发誓有钱一定要买一台好电脑,起码可以装5个linux虚拟机的那种。
退而求其次,我打算使用haystack+whoosh+jieba实现网站的全局搜索功能,whoosh是一个纯python编写的搜索引擎,虽然速度不及java编写的elasticsearch,solr等,但对与一般的中小项目足够用了,最关键的一点是不用再搞各种java环境了。直接在项目中使用whoosh不是一件容易的事,因此需要用到haystack这个全文搜索框架,官网上说:Haystack为Django提供模块化搜索。它具有统一,熟悉的API,允许您插入不同的搜索后端(如Solr, Elasticsearch,Whoosh,Xapian等),而无需修改代码。whoosh自带的分词工具对于中文来说不是太友好,因此我使用了中文分词还算不错的jieba作为分词工具。
第一步:
安装django-haystack,whoosh,jieba

pip install django-haystack
pip install whoosh
pip install jieba

第二步:
配置settings
django中haystack+whoosh+jieba实现网站的全局搜索功能_第1张图片

# 全文检索框架的配置
HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine', # 使用whoosh引擎
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'), # 索引文件的路径
    },
}
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor' # 当添加、修改、删除数据时,自动生成索引
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10 # 指定搜索结果每页的条数

第二步:
生成索引文件
在包含被索引字段的models.py所在的app下新建一个search_indexes.py,名字固定。
django中haystack+whoosh+jieba实现网站的全局搜索功能_第2张图片
在该py文件里创建索引类

from haystack import indexes
from Store.models import Goods

# 对某个类中的某些数据建立索引
class GoodsIndex(indexes.SearchIndex,indexes.Indexable):
    # document=True说明这是一个索引字段,user_template=True表明通过模板来指明索引值由哪些模型类字段组成
    text = indexes.CharField(document=True,use_template=True)

    def get_model(self):
        return Goods # 返回模型类

    def index_queryset(self, using=None):
        return self.get_model().objects.all() # 返回建立索引的数据

django中haystack+whoosh+jieba实现网站的全局搜索功能_第3张图片
第三步:
创建模板文件
user_template=True表明通过模板来指明索引值由哪些模型字段组成,因此需要创建一个模板文件。
该模板文件要创建在templates下
django中haystack+whoosh+jieba实现网站的全局搜索功能_第4张图片
search和indexes文件夹是固定不变的,Store文件夹和存放search_indexes.py文件的app名字相同,txt文件命名格式:所使用模型类类名小写_text.txt
在该文件下填写想要创建索引的字段,格式{{ objects.字段名 }}

# 指明需要生成索引的字段
{{ object.goods_name }} # 使用商品名称建立索引
{{ object.goods_description }} # 使用商品描述建立索引
{{ object.goods_detail }} # 使用商品详情建立索引

django中haystack+whoosh+jieba实现网站的全局搜索功能_第5张图片
第四步:
建立索引数据
命令行输入python manage.py rebuild_index
django中haystack+whoosh+jieba实现网站的全局搜索功能_第6张图片
第五步:
配置路由
django中haystack+whoosh+jieba实现网站的全局搜索功能_第7张图片
修改前端页面
在这里插入图片描述
请求方式为“get”,name为“q”
第六步:
配置jieba分词
在安装的haystack文件下的backends文件夹下新建jiebaanalyzer.py文件。
django中haystack+whoosh+jieba实现网站的全局搜索功能_第8张图片
文件夹里添加如下代码

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 JiebaAnalyzer():
    return ChineseTokenizer()

然后备份whoosh_backend.py文件为whoosh_backend_bak.py,在whoosh_backend.py文件中导入新建的jiebaanalyzer.py
django中haystack+whoosh+jieba实现网站的全局搜索功能_第9张图片
然后找到analyzer=StemmingAnalyzer(),将其改为JiebaAnalyzer()
在这里插入图片描述
最后点击保存。
这样jieba分词就配置完成了。

第七步:
重新建立索引数据
django中haystack+whoosh+jieba实现网站的全局搜索功能_第10张图片
此时我们就可以愉快的使用haystack+whoosh+jieba进行全局搜索了。
当我们输入查找关键词后,haystack会使用whoosh进行匹配,并将相关的数据返回给我们。主要有三个数据:
query:搜索关键字
page:当前页的page对象,包含具体的商品信息
paginator:paginator对象
我们只需要将这些数据通过模板语言渲染到前端页面即可。

你可能感兴趣的:(django,django,haystack,whoosh,jieba)