Django haystack + whoosh + jieba 全文搜索

简介

业务场景

搜索栏输入塑料玩具时,希望优先搜索出 名称简介 中带有 塑料玩具 的条目, 并同时匹配出 塑料玩具玩具塑料塑料玩巨等信息,按照匹配度排序,且支持匹配英文大小写。

技术选型

Django自带的模糊匹配 icontains 表示 Mysql的 like,不满足业务分词需求,且随着数据量增大,消耗的资源和时间都会线性增长,因此考虑使用专门的搜索框架

  • haystack
    搜索框架,用于接入搜索引擎,而无需关注索引建立、搜索解析等细节问题。支持whoosh、elastic search等
  • whoosh
    轻量级全文搜索引擎
  • Elasticsearch
    重量级全文搜索引擎,对服务器性能占用较多,暂不考虑
  • jieba
    用于替换whoosh自带的分词器,以支持中文分词

安装配置

pip install django-haystack
pip install whoosh
pip install jieba
# settings.py
INSTALLED_APPS = (
    ...
    'haystack', #将haystack放在最后
)

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine', # 如覆写了Whoosh引擎,则此处为自定义引擎位置
        'PATH': os.path.join(BASE_DIR, 'whoosh_index'),# 索引文件位置
    }
}
# 监听Django更新数据库数据,自动更新索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'
# 查询加载数据量 默认为 10
HAYSTACK_ITERATOR_LOAD_PER_QUERY = 500
# 默认为AND
HAYSTACK_DEFAULT_OPERATOR = 'OR'
search_indexes.py

在需要全文搜索的应用目录下,新增search_indexes.py文件

  • document=True
    每个索引类中只能有一个字段具有该属性,haystack将使用此字段的内容作为索引进行检索(primary field)。通常将该字段命名为text
  • use_template=True
    为模型中,/templates/search/indexes/应用名称/模型类名称_text.txt文件中的字段创建索引

如下,前端在索引的时候,可以按照text=xxx,也可以按照id=xxx,name=xxx等,我们的数据返回也是返回id,name,price

# search_indexes.py

from haystack import indexes
from .models import Blog   # 引入自己的model

# 类名必须为需要检索的Model名+Index
class BlogIndex(indexes.SearchIndex, indexes.Indexable):
    text = indexes.CharField(document=True, use_template=True)
    
# 此外可以存在,可以不存在,看具体需要的数据    
    id = indexes.IntegerField(model_attr='id')
    name = indexes.CharField(model_attr='name')
    price = indexes.DecimalField(model_attr='price')

    def get_model(self):
        return Blog                     # 添加自己model

    def index_queryset(self, using=None):
        return self.get_model().objects.filter(is_delete=0)
# templates/search/indexes/blog/blog_text.txt
{{ object.title }}
{{ object.body }}
使用 jieba 中文分词

复制haystack/backends/whoosh_backend.py到自己的app 路径下,并添加修改如下内容:

# 顶部引入jieba中的中文分词器
from jieba.analyse import ChineseAnalyzer

# 在整个py文件中,查找
analyzer=StemmingAnalyzer()
全部改为改为
analyzer=ChineseAnalyzer()
总共大概有两三处吧

修改完成后,应修改settings.py中ENGINE指向该新文件

使用命令首次生成索引
python manage.py rebuild_index
在view中使用
class VisitorQuotationView(viewsets.GenericViewSet):
    # 列表数据
    def list(self, request, *args, **kwargs):
        key = request.GET.get('key', "")
        all_results = SearchQuerySet().auto_query(key).models(Quotation)
        return Response({'data': all_results }, status=status.HTTP_200_OK)

你可能感兴趣的:(Django haystack + whoosh + jieba 全文搜索)