栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

Django中使用haystack+whoosh实现搜索功能

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

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 文件,截图如下:

在 search_indexes.py 文件中加入以下内容

# 定义索引类
from haystack import indexes
# 导入你的模型类
from goods.models import GoodsSKU
# 指定对于某个类的某些数据建立索引
# 索引类名格式:模型类名+Index
class GoodsSKUIndex(indexes.SearchIndex, indexes.Indexable):
 # 索引字段 use_template=True指定根据表中的哪些字段建立索引文件的说明放在一个文件中
 text = indexes.CharField(document=True, use_template=True)
 def get_model(self):
  # 返回你的模型类
  return GoodsSKU
 # 建立索引的数据
 def index_queryset(self, using=None):
  return self.get_model().objects.all()

指定要检索的内容

在templates文件夹下面新建search文件夹,在search文件夹下面新建indexes文件夹,在indexes文件夹下面新建要检索应用名的文件夹比如goods文件夹,在goods文件夹下面新建 表名_text.txt,表名小写,所以目前的目录结构是这样的 templates/search/indexes/goods/goodssku_text.txt ,截图如下:

在goodssku_text.txt 文件中指定你要根据表中的哪些字段建立索引数据,现在我们要根据商品的名称,简介,详情来建立索引,如下配置

# 指定根据表中的哪些字段建立索引数据
{{ object.name }} # 根据商品的名称建立索引
{{ object.desc }} # 根据商品的简介建立索引
{{ object.goods.detail }} # 根据商品的详情建立索引

其中的objects可以理解为数据表对应的商品对象。

生成索引文件

使用pycharm自带的命令行terminal运行以下命令生成索引文件:

python manage.py rebuild_index

运行成功后,你可以在项目下看到类似如下索引文件

使用全文检索

通过如上的配置,我们的数据索引已经建立了,现在我们要在项目中使用全文检索。

在需要使用检索的地方进行 form 表单改造



如上所示,其中要注意的是:

发送方式必须使用get;

搜索的input框 name 必须是 q;

配置检索对应的url

在项目下的urls.py文件中添加如下url配置

urlpatterns = [
 url(r'^search/', include('haystack.urls')), # 全文检索框架
]

检索成功后生成的参数

当haystack自动检索成功后,会给我们返回三个参数;

query参数,表示你查询的参数;

page参数,当前页的Page对象,是查询到的对象的集合,可以通过for循环类获取单个商品,通过 商品.objects.xxx 获取商品对应的字段;

paginator参数,分页paginator对象。

可以通过如下代码测试参数




 
 Title

搜索的关键字:{{ query }}
当前页的Page对象:{{ page }}
    {% for item in page %}
  • {{ item.object }}
  • {% endfor %}
分页paginator对象:{{ paginator }}

templates/indexes/search.html

注意,位置和文件名都是固定的,并且这只是测试文件,后面使用全文检索时记得不能使用search.html,改成其他名字。

数据+search.html返回渲染后页面

当haystack全文检索后会返回数据,现在我们需要一个页面来接收这些数据,并且在页面渲染后返回这个页面给用户观看,渲染并返回页面的工作haystack已经帮我们做了,那么我们现在只需要准备一个页面容纳数据即可。

在templates文件夹下的indexes文件夹下新建一个search.html,注意路径和文件名是固定的,如下图

利用检索返回的参数在search.html中定义要渲染出的模板和样式,我的页面如下


 {{ query }}
 >
 搜索结果如下:


 
    {% for item in page %}
  • {{ item.object.name }} ¥{{ item.object.price }} {{ item.object.price}}/{{ item.object.unite }}
  • {% endfor %}
{% if page.has_previous %} <上一页 {% endif %} {% for pindex in paginator.page_range %} {% if pindex == page.number %} {{ pindex }} {% else %} {{ pindex }} {% endif %} {% endfor %} {% if page.has_next %} 下一页> {% endif %}

search.html

至此,我们可以在页面上搜索一下内容,应该是能成功的,但也有可能不会返回任何数据就算name就是你搜索的内容,这是因为我们现在使用的主要还是为英语服务的分词包,接下来我们要配置使用中文分词包了。

使用中文分词包jieba

在前面的配置中我们已经安装了jieba;

创建 ChineseAnalyzer.py 文件

进入虚拟环境下的 Libsite-packageshaystackbackends 目录下新建 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 文件

直接在 虚拟环境下的 Libsite-packageshaystackbackends 目录下复制一份 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+whoosh实现搜索功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对考高分网网站的支持!
如果你觉得本文对你有帮助,欢迎转载,烦请注明出处,谢谢!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/23755.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号