Python中使用haystack实现django全文检索搜索引擎功能


Posted in Python onAugust 26, 2017

前言

django是python语言的一个web框架,功能强大。配合一些插件可为web网站很方便地添加搜索功能。

搜索引擎使用whoosh,是一个纯python实现的全文搜索引擎,小巧简单。

中文搜索需要进行中文分词,使用jieba。

直接在django项目中使用whoosh需要关注一些基础细节问题,而通过haystack这一搜索框架,可以方便地在django中直接添加搜索功能,无需关注索引建立、搜索解析等细节问题。

haystack支持多种搜索引擎,不仅仅是whoosh,使用solr、elastic search等搜索,也可通过haystack,而且直接切换引擎即可,甚至无需修改搜索代码。

配置搜索

1.安装相关包

pip install django-haystack
pip install whoosh
pip install jieba

2.配置django的settings

修改settings.py文件,添加haystack应用:

INSTALLED_APPS = (
  ...
  'haystack', #将haystack放在最后
)

在settings中追加haystack的相关配置:

HAYSTACK_CONNECTIONS = {
  'default': {
    'ENGINE': 'haystack.backends.whoosh_cn_backend.WhooshEngine',
    'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
  }
}
# 添加此项,当数据库改变时,会自动更新索引,非常方便
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

3.添加url

在整个项目的urls.py中,配置搜索功能的url路径:

urlpatterns = [
  ...
  url(r'^search/', include('haystack.urls')),
]

4.在应用目录下,添加一个索引

在子应用的目录下,创建一个名为 search_indexes.py 的文件。

from haystack import indexes
# 修改此处,为你自己的model
from models import GoodsInfo
# 修改此处,类名为模型类的名称+Index,比如模型类为GoodsInfo,则这里类名为GoodsInfoIndex
class GoodsInfoIndex(indexes.SearchIndex, indexes.Indexable):
  text = indexes.CharField(document=True, use_template=True)
  def get_model(self):
    # 修改此处,为你自己的model
    return GoodsInfo
  def index_queryset(self, using=None):
    return self.get_model().objects.all()

说明:

1)修改上文中三处注释即可

2)此文件指定如何通过已有数据来建立索引。get_model处,直接将django中的model放过来,便可以直接完成索引啦,无需关注数据库读取、索引建立等细节。

3)text=indexes.CharField一句,指定了将模型类中的哪些字段建立索引,而use_template=True说明后续我们还要指定一个模板文件,告知具体是哪些字段

5.指定索引模板文件

在项目的“templates/search/indexes/应用名称/”下创建“模型类名称_text.txt”文件。

例如,上面的模型类名称为GoodsInfo,则创建goodsinfo_text.txt(全小写即可),此文件指定将模型中的哪些字段建立索引,写入如下内容:(只修改中文,不要改掉object)

{{ object.字段1 }}
{{ object.字段2 }}
{{ object.字段3 }}

6.指定搜索结果页面

在templates/search/下面,建立一个search.html页面。

<!DOCTYPE html>
<html>
<head>
  <title></title>
</head>
<body>
{% if query %}
  <h3>搜索结果如下:</h3>
  {% for result in page.object_list %}
    <a href="/{{ result.object.id }}/" rel="external nofollow" >{{ result.object.gName }}</a><br/>
  {% empty %}
    <p>啥也没找到</p>
  {% endfor %}

  {% if page.has_previous or page.has_next %}
    <div>
      {% if page.has_previous %}<a href="?q={{ query }}&page={{ page.previous_page_number }}" rel="external nofollow" >{% endif %}« 上一页{% if page.has_previous %}</a>{% endif %}
    |
      {% if page.has_next %}<a href="?q={{ query }}&page={{ page.next_page_number }}" rel="external nofollow" >{% endif %}下一页 »{% if page.has_next %}</a>{% endif %}
    </div>
  {% endif %}
{% endif %}
</body>
</html>

7.使用jieba中文分词器

在haystack的安装文件夹下,路径如“/home/python/.virtualenvs/django_py2/lib/python2.7/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()

8.切换whoosh后端为中文分词

将上面backends目录中的whoosh_backend.py文件,复制一份,名为whoosh_cn_backend.py,然后打开此文件,进行替换:

# 顶部引入刚才添加的中文分词
from .ChineseAnalyzer import ChineseAnalyzer 
# 在整个py文件中,查找
analyzer=StemmingAnalyzer()

全部改为改为

analyzer=ChineseAnalyzer()

总共大概有两三处吧

9.生成索引

手动生成一次索引:

python manage.py rebuild_index

10.实现搜索入口

在网页中加入搜索框:

<form method='get' action="/search/" target="_blank">
  <input type="text" name="q">
  <input type="submit" value="查询">
</form>

丰富的自定义

上面只是快速完成一个基本的搜索引擎,haystack还有更多可自定义,来实现个性化的需求。

参考官方文档:http://django-haystack.readthedocs.io/en/master/

自定义搜索view

上面的配置中,搜索相关的请求被导入到haystack.urls中,如果想自定义搜索的view,实现更多功能,可以修改。

haystack.urls中内容其实很简单,

from django.conf.urls import url 
from haystack.views import SearchView 
urlpatterns = [ 
  url(r'^$', SearchView(), name='haystack_search'), 
]

那么,我们写一个view,继承自SearchView,即可将搜索的url导入到自定义view中处理啦。

class MySearchView(SearchView):
# 重写相关的变量或方法
template = 'search_result.html'

查看SearchView的源码或文档,了解每个方法是做什么的,便可有针对性地进行修改。

比如,上面重写了template变量,修改了搜索结果页面模板的位置。

高亮

在搜索结果页的模板中,可以使用highlight标签(需要先load一下)

{% highlight <text_block> with <query> [css_class "class_name"] [html_tag "span"] [max_length 200] %}

text_block即为全部文字,query为高亮关键字,后面可选参数,可以定义高亮关键字的html标签、css类名,以及整个高亮部分的最长长度。

高亮部分的源码位于 haystack/templatetags/lighlight.py haystack/utils/lighlighting.py文件中,可复制进行修改,实现自定义高亮功能。

总结

以上所述是小编给大家介绍的Python中使用haystack实现django全文检索搜索引擎功能,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对三水点靠木网站的支持!

Python 相关文章推荐
python实现图片批量剪切示例
Mar 25 Python
详解Python3中的Sequence type的使用
Aug 01 Python
基于python实现的抓取腾讯视频所有电影的爬虫
Apr 22 Python
python通过pip更新所有已安装的包实现方法
May 19 Python
Django对数据库进行添加与更新的例子
Jul 12 Python
python笔记_将循环内容在一行输出的方法
Aug 08 Python
python tkinter基本属性详解
Sep 16 Python
关于torch.optim的灵活使用详解(包括重写SGD,加上L1正则)
Feb 20 Python
Python reversed函数及使用方法解析
Mar 17 Python
如何在pycharm中安装第三方包
Oct 27 Python
python正则表达式re.match()匹配多个字符方法的实现
Jan 27 Python
python matplotlib工具栏源码探析三之添加、删除自定义工具项的案例详解
Feb 25 Python
python读取excel表格生成erlang数据
Aug 26 #Python
使用Python实现简单的服务器功能
Aug 25 #Python
详解Python实现多进程异步事件驱动引擎
Aug 25 #Python
python基础while循环及if判断的实例讲解
Aug 25 #Python
itchat和matplotlib的结合使用爬取微信信息的实例
Aug 25 #Python
用 Python 爬了爬自己的微信朋友(实例讲解)
Aug 25 #Python
详解python基础之while循环及if判断
Aug 24 #Python
You might like
深入理解PHP变量的值类型和引用类型
2015/10/21 PHP
PHP截取IE浏览器并缩小原图的方法
2016/03/04 PHP
CI框架(CodeIgniter)实现的数据库增删改查操作总结
2018/05/23 PHP
JQuery 获得绝对,相对位置的坐标方法
2010/02/09 Javascript
PHP中CURL的几个经典应用实例
2015/01/23 Javascript
js改变embed标签src值的方法
2015/04/10 Javascript
javascript瀑布流布局实现方法详解
2016/02/17 Javascript
Bootstrap和Java分页实例第二篇
2016/12/23 Javascript
jQuery点击弹出层弹出模态框点击模态框消失代码分享
2017/01/21 Javascript
jQuery实现标签页效果实战(4)
2017/02/08 Javascript
nodejs socket实现的服务端和客户端功能示例
2017/06/02 NodeJs
详解vue项目中如何引入全局sass/less变量、function、mixin
2018/06/02 Javascript
this在vue和小程序中的使用详解
2019/01/28 Javascript
使用jquery的cookie实现登录页记住用户名和密码的方法
2019/03/13 jQuery
layui checkbox默认选中,获取选中值,清空所有选中项的例子
2019/09/02 Javascript
使用layui前端框架弹出form表单以及提交的示例
2019/10/25 Javascript
vue自定义指令实现仅支持输入数字和浮点型的示例
2019/10/30 Javascript
vue+flask实现视频合成功能(拖拽上传)
2021/03/04 Vue.js
Python 爬虫之超链接 url中含有中文出错及解决办法
2017/08/03 Python
在python2.7中用numpy.reshape 对图像进行切割的方法
2018/12/05 Python
总结Python图形用户界面和游戏开发知识点
2019/05/22 Python
python 寻找离散序列极值点的方法
2019/07/10 Python
Python Pandas 对列/行进行选择,增加,删除操作
2020/05/17 Python
python在地图上画比例的实例详解
2020/11/13 Python
无谷物狗粮:Pooch & Mutt
2018/05/23 全球购物
Super-Pharm波兰:药房和香水在一个地方
2020/08/18 全球购物
什么是静态路由,其特点是什么?什么是动态路由,其特点是什么?
2013/07/26 面试题
如何写好优秀的创业计划书
2014/01/30 职场文书
《陈涉世家》教学反思
2014/04/12 职场文书
应聘护士求职信
2014/07/21 职场文书
村当支部个人对照检查材料思想汇报
2014/10/06 职场文书
道德模范事迹材料
2014/12/20 职场文书
网络研修心得体会
2016/01/08 职场文书
干货分享:推荐信写作技巧!
2019/06/21 职场文书
2019年暑期安全广播稿!
2019/07/03 职场文书
Windows server 2012 R2 安装IIS服务器
2022/04/29 Servers