Django内容搜索框功能-----Haystack框架、Jieba分词、Whoosh引擎

背景

在前端实现 搜索框输入内容后,出现与内容相匹配的数据,效果类似于模糊查询

一、安装库

需安装django-haystack、whoosh、jieba库

pip install django-haystack==2.7.0 -i https://pypi.tuna.tsinghua.edu.cn/simple

pip install whoosh

pip install jieba

二、相关配置

1、注册haystack

settings.py中注册应用 ‘haystack’

INSTALLED_APPS = [
	'xxx',
	...
	'xxx',
	'haystack',
]

2、配置框架的引擎whoosh

settings.py中添加以下固定配置:

# 全文检索框架
HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_backend.WhooshEngine',
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    },
}

# 自动更新索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

3、建立索引

①、在需添加搜索的应用下创建名为search_indexes.py的文件

(search_indexes.py与views.py、models.py在同一级目录)
search_indexes.py是固定的文件名字!
search_indexes.py是固定的文件名字!
search_indexes.py是固定的文件名字!
以article应用为例,
article/search_indexes.py文件内容如下:

from .models import Article
from haystack import indexes


# !!!类名必须为需要检索的ModelName+Index,如这里需要检索Article,所以创建:ArticleIndex
class ArticleIndex(indexes.SearchIndex, indexes.Indexable):
    # 创建一个用于接收搜索框内容的字段text
    # use_template根据哪些字段建立索引,将说明放入一个文件中
    text = indexes.CharField(document=True, use_template=True)  
	
	# 重载get_model方法,必须要有!
    def get_model(self):  
        return Article
        
    # 建立索引的数据
    def index_queryset(self, using=None):
        return self.get_model().objects.all()

(此处为基础内容供参考,可根据具体情况修改,实际修改只需改全文三处模型名称 Article 即可

②、建立索引文件

在项目的总templates文件夹下 创建 templates/search/indexes/应用名文件夹/模型类名_text.txt
在这里插入图片描述
注意:

  • search 文件夹名称固定
  • indexes 文件夹名称固定
  • txt文件的命名规则为:模型类名_text.txt
③、设置引擎的索引内容

这里设置的是搜索内容的匹配范围,即与数据表的哪些字段内容相匹配。
article_text.txt文件内容设置如下(具体根据模型内容改变):

{{ object.title }}
{{ object.desc }}
{{ object.content }}

在这里插入图片描述

4、生成索引内容文件

即根据设置索引值,预先读取出数据库内容,单独放置,以供引擎搜索。

①、打开一个Terminal窗口,在项目路径下执行:

D:Afile/bfile/XxxProjects> python manage.py rebuild_index

②、输入 y 确认创建。

— 至此配置结束 —

5、简单测试效果

①、配置search路由

urls.py主路由列表中添加:

url(r’^search/', include(‘haystack.urls’)),

②、启动Django服务,打开一个Terminal窗口,在项目路径下执行:

D:Afile/bfile/XxxProjects> python manage.py runserver

③、浏览器中输入搜索(?q=什么随便):

http://127.0.0.1:8000/search/?q=sxxs

④、配置正常,则在此时出现黄色警告页面(否则再查看一下配置内容):

在这里插入图片描述

6、编写搜索界面

在search文件夹下创建search.html文件(固定名字,不可变)
在这里插入图片描述
search.html 文件内容如下(参考):

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>Title</title>
</head>
<body>
搜索:{{ query }}<br>
page:{{ page }}<br>
{% for item in page %}
    {{ item.object.id }} 《 {{ item.object.title }} 》 - {{ item.object.desc }} <br>
{% endfor %}
count:{{ paginator.count }}
</body>
</html>

7、正式搜索

浏览器输入: (查询不同内容修改 ?q=不同内容)

http://127.0.0.1:8000/search/?q=内容

此时,多次测试发现:搜索结果不尽如人意,只有输入完整的原文才能查询出结果,输入词语进行模糊查询 基本没用返回结果。

问题:

whoosh搜索引擎自带的中文分词功能效果较差

解决:

为whoosh搜索引擎配置jieba库进行分词。

三、配置jieba分词

①、haystack 添加ChineseAnalyzer.py文件

找到本项目使用的site-packages文件夹
鼠标悬停即可看到包的安装路径:
在这里插入图片描述

进入 Lib\site-packages\haystack\backends
在backends文件夹中添加ChineseAnalyzer.py文件(新建txt文件,之后改后缀):
在这里插入图片描述
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()

②、修改whoosh_bcakend.py文件

1、复制whoosh_bcakend.py文件
2、原地粘贴whoosh_bcakend.py文件,改名为whoosh_cn_backend.py
3、修改whoosh_cn_backend.py内容

#导入添加的ChineseAnalyzer文件
from .ChineseAnalyzer import ChineseAnalyzer
xxx
xxx
xxx
#164行左右修改
TEXT(…,analyzer=ChineseAnalyzer(),…)

③、修改sittings.py文件whoosh配置

将原来引用的whoosh_backend,修改为新配置的whoosh_cn_backend:

# 全文检索框架
HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
    },
}

# 自动更新索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

④、重新生成索引文件

Terminal窗口再次执行:

D:Afile/bfile/XxxProjects> python manage.py rebuild_index

⑤、再次测试搜索

另一个Terminal窗口执行启动django服务:

D:Afile/bfile/XxxProjects> python manage.py runserver

浏览器搜索:
在这里插入图片描述
搜索效果显著提升。

四、ajax渲染数据

可以通过ajax渲染的方式使数据的展示更加灵活。

1、创建视图函数

在应用下的views.py文件中创建:

def searchJson(request):
    from haystack.query import SearchQuerySet, Raw
    qParams = request.GET.get('q')
    if not qParams:
        return JsonResponse({
            'code': 400,
            'msg': '缺少参数'
        })
    articles = SearchQuerySet().filter(text=Raw(qParams)).order_by('view_num')  # 根据浏览量排序显示

    res_list = []

    try:
        for article in articles:
            ar_data = {}
            ar_data['id'] = article.object.id
            ar_data['title'] = article.object.title
            res_list.append(ar_data)
    except:
        pass

    return JsonResponse({
        'code': 200,
        'data': res_list
    },json_dumps_params={'ensure_ascii': False})

2、索引数据添加view_num

在应用里的search_indexes.py文件中改写添加view_num:

class ArticleIndex(indexes.SearchIndex, indexes.Indexable):
    # 类名必须为需要检索的Model_name+Index,这里需要检索Article,所以创建ArticleIndex
    # use_template根据哪些字段建立索引,将说明放入一个文件中
    text = indexes.CharField(document=True, use_template=True)  # 创建一个text字段
    view_num = indexes.CharField(model_attr='view_num')  # 变量名自定义且和视图函数保持一致

    def get_model(self):  # 重载get_model方法,必须要有!
        return Article

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

3、配置主路由

url(r’^searchJson/', searchJson),

4、配置ajax请求

在search.html中添加:

{% load static from staticfiles %}
<script type="text/javascript" src="{% static 'jquery.min.js' %}"></script>
<script>
    $.ajax({
		url:'/searchJson?q=框架', success(res){
		console.log(res)
		}
})
</script>

5、搜索

在这里插入图片描述

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值