Django Haystack 简介

django-haystack 是一个专门提供搜索功能的 django 第三方应用,它支持 Solr、Elasticsearch、Whoosh、Xapian 等多种搜索引擎,配合中文自然语言处理库 jieba 分词,就可以为博客提供博客文章搜索系统。

安装必要依赖

  • Whoosh。Whoosh 是一个由纯 Python 实现的全文搜索引擎,没有二进制文件等,比较小巧,配置简单方便。
  • jieba 中文分词。由于 Whoosh 自带的是英文分词,对中文的分词支持不是太好,所以使用 jieba 替换Whoosh 的分词组件。

pip install whoosh django-haystack jieba

配置 Haystack

安装好 django haystack 后需要在项目的 settings.py 做一些简单的配置。

首先是把 django haystack 加入到 INSTALLED_APPS 选项里:

blogproject/settings.py

INSTALLED_APPS = [
'django.contrib.admin',
# 其它 app...
'haystack',
'blog',
'comments',
]

然后加入如下配置项:

HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'blog.whoosh_cn_backend.WhooshEngine',
'PATH': os.path.join(BASE_DIR, 'whoosh_index'),
},
}
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 10
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

HAYSTACK_CONNECTIONS 的 ENGINE 指定了 django haystack 使用的搜索引擎,这里我们使用了 blog.whoosh_cn_backend.WhooshEngine,虽然目前这个引擎还不存在,但我们接下来会创建它。PATH 指定了索引文件需要存放的位置,我们设置为项目根目录 BASE_DIR 下的 whoosh_index 文件夹(在建立索引是会自动创建)。

HAYSTACK_SEARCH_RESULTS_PER_PAGE 指定如何对搜索结果分页,这里设置为每 10 项结果为一页。

HAYSTACK_SIGNAL_PROCESSOR 指定什么时候更新索引,这里我们使用haystack.signals.RealtimeSignalProcessor,作用是每当有文章更新时就更新索引。由于博客文章更新不会太频繁,因此实时更新没有问题。

处理数据

接下来就要告诉 django haystack 使用那些数据建立索引以及如何存放索引。如果要对 blog 应用下的数据进行全文检索,做法是在 blog 应用下建立一个 search_indexes.py 文件,写上如下代码:

blog/search_indexes.py

from haystack import indexes
from .models import Post class PostIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True, use_template=True) def get_model(self):
return Post def index_queryset(self, using=None):
return self.get_model().objects.all()

这是 django haystack 的规定。要相对某个 app 下的数据进行全文检索,就要在该 app 下创建一个 search_indexes.py 文件,然后创建一个 XXIndex 类(XX 为含有被检索数据的模型,如这里的 Post),并且继承 SearchIndex 和 Indexable

每个索引里面必须有且只能有一个字段为 document=True,这代表 django haystack 和搜索引擎将使用此字段的内容作为索引进行检索(primary field)。注意,如果使用一个字段设置了document=True,则一般约定此字段名为text,这是在 SearchIndex 类里面一贯的命名,以防止后台混乱

并且,haystack 提供了use_template=True 在 text 字段中,这样就允许我们使用数据模板去建立搜索引擎索引的文件,说得通俗点就是索引里面需要存放一些什么东西,例如 Post 的 title 字段,这样我们可以通过 title 内容来检索 Post 数据了。举个例子,假如你搜索 Python ,那么就可以检索出 title 中含有 Python 的Post了,怎么样是不是很简单?数据模板的路径为 templates/search/indexes/youapp/\<model_name>_text.txt(例如 templates/search/indexes/blog/post_text.txt),其内容为:

templates/search/indexes/blog/post_text.txt

{{ object.title }}
{{ object.body }}

这个数据模板的作用是对 Post.title、Post.body 这两个字段建立索引,当检索的时候会对这两个字段做全文检索匹配,然后将匹配的结果排序后作为搜索结果返回。

配置 URL

接下来就是配置 URL,搜索的视图函数和 URL 模式 django haystack 都已经帮我们写好了,只需要项目的 urls.py 中包含它:

blogproject/urls.py

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

另外在此之前我们也为自己写的搜索视图配置了 URL,把那个 URL 删掉,以免冲突:

blog/urls.py

# url(r'^search/$', views.search, name='search'),

修改搜索表单

修改一下搜索表单,让它提交数据到 django haystack 搜索视图对应的 URL:

<form role="search" method="get" id="searchform" action="{% url 'haystack_search' %}">
<input type="search" name="q" placeholder="搜索" required>
<button type="submit"><span class="ion-ios-search-strong"></span></button>
</form>

主要是把表单的 action 属性改为 {% url 'haystack_search' %}

创建搜索结果页面

haystack_search 视图函数会将搜索结果传递给模板 search/search.html,因此创建这个模板文件,对搜索结果进行渲染:

templates/search/search.html

{% extends 'base.html' %}
{% load highlight %} {% block main %}
{% if query %}
{% for result in page.object_list %}
<article class="post post-{{ result.object.pk }}">
<header class="entry-header">
<h1 class="entry-title">
<a href="{{ result.object.get_absolute_url }}">{% highlight result.object.title with query %}</a>
</h1>
<div class="entry-meta">
<span class="post-category">
<a href="{% url 'blog:category' result.object.category.pk %}">
{{ result.object.category.name }}</a></span>
<span class="post-date"><a href="#">
<time class="entry-date" datetime="{{ result.object.created_time }}">
{{ result.object.created_time }}</time></a></span>
<span class="post-author"><a href="#">{{ result.object.author }}</a></span>
<span class="comments-link">
<a href="{{ result.object.get_absolute_url }}#comment-area">
{{ result.object.comment_set.count }} 评论</a></span>
<span class="views-count"><a
href="{{ result.object.get_absolute_url }}">{{ result.object.views }} 阅读</a></span>
</div>
</header>
<div class="entry-content clearfix">
<p>{% highlight result.object.body with query %}</p>
<div class="read-more cl-effect-14">
<a href="{{ result.object.get_absolute_url }}" class="more-link">继续阅读 <span
class="meta-nav">→</span></a>
</div>
</div>
</article>
{% empty %}
<div class="no-post">没有搜索到你想要的结果!</div>
{% endfor %}
{% if page.has_previous or page.has_next %}
<div>
{% if page.has_previous %}
<a href="?q={{ query }}&amp;page={{ page.previous_page_number }}">{% endif %}&laquo; Previous
{% if page.has_previous %}</a>{% endif %}
|
{% if page.has_next %}<a href="?q={{ query }}&amp;page={{ page.next_page_number }}">{% endif %}Next
&raquo;{% if page.has_next %}</a>{% endif %}
</div>
{% endif %}
{% else %}
请输入搜索关键词,例如 django
{% endif %}
{% endblock main %}

这个模板基本和 blog/index.html 一样,只是由于 haystack 对搜索结果做了分页,传给模板的变量是一个 page 对象,所以我们从 page 中取出这一页对应的搜索结果,然后对其循环显示,即 {% for result in page.object_list %}。另外要取得 Post(文章)以显示文章的数据如标题、正文,需要从 result 的 object 属性中获取。query 变量的值即为用户搜索的关键词。

高亮关键词

注意到百度的搜索结果页面,含有用户搜索的关键词的地方都是被标红的,在 django haystack 中实现这个效果也非常简单,只需要使用 {% highlight %} 模板标签即可,其用法如下:

# 使用默认值
{% highlight result.summary with query %} # 这里我们为 {{ result.summary }} 里所有的 {{ query }} 指定了一个<div></div>标签,并且将class设置为highlight_me_please,这样就可以自己通过CSS为{{ query }}添加高亮效果了,怎么样,是不是很科学呢
{% highlight result.summary with query html_tag "div" css_class "highlight_me_please" %} # 可以 max_length 限制最终{{ result.summary }} 被高亮处理后的长度
{% highlight result.summary with query max_length 40 %}

在博客文章搜索页中我们对 title 和 body 做了高亮处理:{% highlight result.object.title with query %},{% highlight result.object.body with query %}。高亮处理的原理其实就是给文本中的关键字包上一个 span 标签并且为其添加 highlighted 样式(当然你也可以修改这个默认行为,具体参见上边给出的用法)。因此我们还要给 highlighted 类指定样式,在 base.html 中添加即可:

base.html

<head>
<title>Black &amp; White</title>
...
<style>
span.highlighted {
color: red;
}
</style>
...
</head>

修改搜索引擎为中文分词

我们使用 Whoosh 作为搜索引擎,但在 django haystack 中为 Whoosh 指定的分词器是英文分词器,可能会使得搜索结果不理想,我们把这个分词器替换成 jieba 中文分词器。从你安装的 haystack 中把 haystack/backends/whoosh_backends.py 文件拷贝到 blog/ 下,重命名为 whoosh_cn_backends.py(之前我们在 settings.py 中 的 HAYSTACK_CONNECTIONS 指定的就是这个文件),然后找到如下一行代码 第164行:

schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=StemmingAnalyzer(), field_boost=field_class.boost, sortable=True)

将其中的 analyzer 改为 ChineseAnalyzer,当然为了使用它,你需要在文件顶部引入:from jieba.analyse import ChineseAnalyzer。

from jieba.analyse import ChineseAnalyzer

...
#注意先找到这个再修改,而不是直接添加
schema_fields[field_class.index_fieldname] = TEXT(stored=True, analyzer=ChineseAnalyzer(),field_boost=field_class.boost, sortable=True)

建立索引文件

最后一步就是建立索引文件了,运行命令 python manage.py rebuild_index 就可以建立索引文件了。

出现警告选择y

结果

Django Haystack 全文检索与关键词高亮的更多相关文章

  1. php-设置关键词高亮的字符串处理函数

    /** * 设置关键词高亮的字符串处理函数 * @param [string] $str [要高亮的字符串] * @param array $word_arr [关键词] */function set ...

  2. 和我一起打造个简单搜索之SpringDataElasticSearch关键词高亮

    前面几篇文章详细讲解了 ElasticSearch 的搭建以及使用 SpringDataElasticSearch 来完成搜索查询,但是搜索一般都会有搜索关键字高亮的功能,今天我们把它给加上. 系列文 ...

  3. jQuery实现页面关键词高亮

    示例代码,关键位置做了注释,请查看代码: <html> <head> <title>jQuery实现页面关键词高亮</title> <style ...

  4. 微信小程序--搜索关键词高亮

    代码地址如下:http://www.demodashi.com/demo/14249.html 一.前期准备工作 软件环境:微信开发者工具 官方下载地址:https://mp.weixin.qq.co ...

  5. 3.6 Lucene基本检索+关键词高亮+分页

    3.2节我们已经运行了一个Lucene实现检索的小程序,这一节我们将以这个小程序为例,讲一下Lucene检索的基本步骤,同时介绍关键词高亮显示和分页返回结果这两个有用的技巧. 一.Lucene检索的基 ...

  6. django haystack报错: ModuleNotFoundError: No module named 'blog.whoosh_cn_backend'

    在配置django haystack时报错: 解决方案: 将ENGINE的值 改为 这样就可以了.

  7. Django:haystack全文检索详细教程

    参考:https://blog.csdn.net/AC_hell/article/details/52875927 一.安装第三方库及配置 1.1 安装插件 pip install whoosh dj ...

  8. haystack(django的全文检索模块)

    haystack haystack是django开源的全文搜索框架 全文检索:标题可以检索,内容也可以检索 支持solr ,elasticsearch,whoosh 1.注册app 在setting. ...

  9. 2 Match、Filter、排序、分页、全文检索、短语匹配、关键词高亮

    查索引内所有文档记录 GET  /beauties/my/_search   GET  /beauties/my/_search {     "query":{         & ...

随机推荐

  1. Html行内元素和块级元素

    1.关于行内元素和块状元素的说明 根据CSS规范的规定,每一个网页元素都有一个display属性,用于确定该元素的类型,每一个元素都有默认的display属性值,比如div元素,它的默认display ...

  2. ArXiv最受欢迎开源深度学习框架榜单:TensorFlow第一,PyTorch第四

    [导读]Kears作者François Chollet刚刚在Twitter贴出最近三个月在arXiv提到的深度学习框架,TensorFlow不出意外排名第一,Keras排名第二.随后是Caffe.Py ...

  3. 【HNOI 2002 】营业额统计(splay)

    题面 Description Tiger最近被公司升任为营业部经理,他上任后接受公司交给的第一项任务便是统计并分析公司成立以来的营业情况. Tiger拿出了公司的账本,账本上记录了公司成立以来每天的营 ...

  4. 笔记:基于DCNN的图像语义分割综述

    写在前面:一篇魏云超博士的综述论文,完整题目为<基于DCNN的图像语义分割综述>,在这里选择性摘抄和理解,以加深自己印象,同时达到对近年来图像语义分割历史学习和了解的目的,博古才能通今!感 ...

  5. 【Webpack的使用指南 01】Webpack入门

    使用Webpack有一段时间了,但是感觉之前学的用的都比较零散,所以在这里整理一下Webpack的使用知识,从入门到进阶. 创建项目 首先创建最简单的一个项目 npm init 得到以下项目结构: 安 ...

  6. 【Spring源码分析】Bean加载流程概览

    代码入口 之前写文章都会啰啰嗦嗦一大堆再开始,进入[Spring源码分析]这个板块就直接切入正题了. 很多朋友可能想看Spring源码,但是不知道应当如何入手去看,这个可以理解:Java开发者通常从事 ...

  7. 在windows8.1下安装ubuntu16.04

    (一)首先来简要了解一些linux的概念! 1.发行版本和内核版本的区别与联系:linux发行版本是"内核版本+一系列挂载软件"的集合体,光是一个内核版本是无法当做操作系统运行的. ...

  8. Jenkins 部署 jmeter + Ant

    安装Jenkins: 到jenkins官网下载相应的jenkins版本: 双击jenkins.msi启动安装,安装目录选择D:\Progrom Files\Jenkins,然后启动成功. Jenkin ...

  9. Docker基础知识整理

    Docker 1.安装2.三大组件 镜像/容器/仓库3.Docker数据管理4.构建Docker5.docker部署微服务 项目部署到Linux服务器 1.安装jdk2.安装tomcat3.将项目wa ...

  10. java语言环境jdk的安装和环境变量的配置

    一.jdk的安装 我安装的为64位的1.7.0_17版本的jdk,双击运行,全部默认下一步就行 此处可整改安装目录,然后点击下一步进行安装. 二.环境变量的配置 1.右键点击我的电脑à点击属性,出现如 ...