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.pyINSTALLED_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.pyfrom haystack import indexes
from .models import Postclass PostIndex(indexes.SearchIndex, indexes.Indexable):text = indexes.CharField(document=True, use_template=True)def get_model(self):return Postdef 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.pyurlpatterns = [# 其它...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"><ahref="{{ 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">继续阅读 <spanclass="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. scrapy 搜索关键字_Scrapy 新浪微博搜索爬虫

    微博高级搜索 可能你经常有这样的需要,比如最近有热度的事件兴起,你要抓取几月几号到几月几号这段时间,提及到某个关键词的微博. 这其实是一个非常刚性的需求,这就要采用微博的高级搜索来完成了. 本文采用 ...

  2. php 搜索关键字,PHP获取搜索关键字有关问题_PHP教程

    PHP获取搜索关键字问题 网上找了一段代码想实现获取搜索关健字,测试了一个关健字取不了,是不是这代码无效了,还是那里有BUG? //取搜索来源关健字 function get_keyword($url ...

  3. linux下全盘搜索关键字,Linux 全盘搜索关键字

    redis系列-主从复制 redis自身提供了主从的机制,通过配置可以实现服务的备份(Master->Slave). 配置项 slaveof mas ... DedeCMS Xss+Csrf G ...

  4. 编写文件搜索小程序:1. 输入绝对路径以及搜索关键字,2. 搜索指定路径下(包括子文件夹)中名称包含关键字的所有文件并打印出,3. 将当前操作记录日志

    package com.homework;import java.io.File; import java.io.FileOutputStream; import java.io.IOExceptio ...

  5. js搜索关键字,并高亮显示

    当我们搜索时,总想要自己输入的字体显示为重点,今天我为大家解决这个问题 <!DOCTYPE html> <html lang="en"><head&g ...

  6. angular+TS实现搜索关键字高亮

    前端实现基于后端返回的文档内容关键字搜索高亮 需求背景及技术实现 针对上传的word文档实现关键字搜索高亮 且需要通过向上向下查找按钮实现当前关键字位置高亮颜色不一样 后端返回文档的html内容 前端 ...

  7. 搜索关键字高亮_Django Haystack 全文检索与关键词高亮

    作者:HelloGitHub-追梦人物[1] 文中所涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库[2] 点击本文最下方的"阅读原文"即可获取 博客提供 RS ...

  8. Django搜索工具——全文检索

    全文检索不同于特定字段的模糊查询,使用全文检索的效率更高,并且能够对于中文进行分词处理 haystack:全文检索的框架,支持whoosh.solr.Xapian.Elasticsearc四种全文检索 ...

  9. Django建立博客搜索功能(haystack+whoosh+jieba)

    0-效果预览 1-相关说明: haystack 全文检索框架,可配置各种搜索引擎,在Django内相当于app whoosh 搜索引擎 2-whoosh下载与优化 中文分词jieba 下载: pip ...

最新文章

  1. 技术直播:讲一个Python编写监控程序的小故事
  2. [程序员创造力训练 1] 猜单词 - 关于健康
  3. .NET中常见的 IL 指令集
  4. 在 SAP CRM Fiori 应用上给 Opportunity 订单添加 note 的后台执行明细
  5. delphi 获取操作系统版本_Ubuntu 20.04 LTS已可通过Windows 10应用商店获取
  6. html选择同级的元素,jquery获取同级元素
  7. hadoop视频教程下载链接汇总
  8. Vue配置TinyMCE富文本编辑器 + 图片(本地)上传到服务器
  9. 三步解决error Microsoft Visual C++ 14.0 or greater is required. Get it with “Microsoft C++ Build Tools“
  10. 2018年广发证券信息技术部面试总结
  11. 我喜欢两个男人。。。
  12. 7个实用有效的shopify运营策略,跨境电商卖家必知
  13. win7系统设置cmd窗口默认以管理员权限运行
  14. 大学生实习证明怎么获得?
  15. python股票回测源码_Python爬虫回测股票的实例讲解
  16. Python break用法详解
  17. STM32F103代码远程升级(五)基于MQTT协议WiFi远程升级代码的实现
  18. 电脑自动安装一堆软件怎么办?
  19. 2.Prometheus读书笔记:深入Prometheus设计
  20. 企业网站关键词优化的步骤

热门文章

  1. 旗舰手机正在向技术“深水区”挺进
  2. 逻辑代数中的基本规则,代入规则和反演规则,对偶规则
  3. 小白怎么自学Maya?
  4. 英语实用 短语 + 句式
  5. 邮件附件att00.html,我的网易163邮箱收到的邮件里有个这样的附件ATT00002.bin打不开,到底是什么?...
  6. phpmyadmin mysql更新_phpMyAdmin官方下载-phpMyAdmin(MySQL数据库管理)v5.10 最新版-ucbug软件站...
  7. go语言下载安装第三方包
  8. 二叉树的层级遍历/锯齿遍历--Java版
  9. 2023谷歌地图poi资源下载分享
  10. 你对爱人的态度,决定了你的婚姻质量