一:使用的工具
haystack是django的开源搜索框架,该框架支持Solr,Elasticsearch,Whoosh, *Xapian*搜索引擎,不用更改代码,直接切换引擎,减少代码量。
搜索引擎使用Whoosh,这是一个由纯Python实现的全文搜索引擎,没有二进制文件等,比较小巧,配置比较简单,当然性能自然略低。
中文分词Jieba,由于Whoosh自带的是英文分词,对中文的分词支持不是太好,故用jieba替换whoosh的分词组件。
其他:Python 2.7 or 3.4.4, Django 1.8.3或者以上,Debian 4.2.6_3
二:配置说明
现在假设我们的项目叫做Project,有一个myapp的app,简略的目录结构如下。

Project
Project
settings.py
blog
models.py
此models.py的内容假设如下:

from django.db import models
from django.contrib.auth.models import User class Note(models.Model):
user = models.ForeignKey(User)
pub_date = models.DateTimeField()
title = models.CharField(max_length=200)
body = models.TextField() def __str__(self):
return self.title

  

1. 首先安装各工具
pip install whoosh django-haystack jieba

2. 添加 Haystack 到Django的 INSTALLED_APPS
配置Django项目的settings.py里面的INSTALLED_APPS添加Haystack,例子:

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'django.contrib.contenttypes',
'django.contrib.sessions',
'django.contrib.sites',
'haystack', }
3. 修改 你的 settings.py,以配置引擎

本教程使用的是Whoosh,故配置如下:

使用jieba分词

1 将文件whoosh_backend.py(该文件路径为python路径/lib/python2.7.5/site-packages/haystack/backends/whoosh_backend.py)拷贝到app下面,并重命名为           whoosh_cn_backend.py,例如blog/whoosh_cn_backend.py。
 修改如下:

from jieba.analyse import ChineseAnalyzer   #在顶部添加

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

2 在settings.py中修改引擎,如下

import os
HAYSTACK_CONNECTIONS = {
'default': {
'ENGINE': 'blog.whoosh_cn_backend.WhooshEngine', #blog.whoosh_cn_backend便是你刚刚添加的文件
'PATH': os.path.join(BASE_DIR, 'whoosh_index'
},
}

4.创建索引

如果你想针对某个app例如mainapp做全文检索,则必须在mainapp的目录下面建立search_indexes.py文件,文件名不能修改。内容如下:

import datetime
from haystack import indexes
from myapp.models import Note class NoteIndex(indexes.SearchIndex, indexes.Indexable): #类名必须为需要检索的Model_name+Index,这里需要检索Note,所以创建NoteIndex
text = indexes.CharField(document=True, use_template=True) #创建一个text字段 author = indexes.CharField(model_attr='user') #创建一个author字段 pub_date = indexes.DateTimeField(model_attr='pub_date') #创建一个pub_date字段 def get_model(self): #重载get_model方法,必须要有!
return Note def index_queryset(self, using=None): #重载index_..函数
"""Used when the entire index for model is updated."""
return self.get_model().objects.filter(pub_date__lte=datetime.datetime.now())

为什么要创建索引?索引就像是一本书的目录,可以为读者提供更快速的导航与查找。在这里也是同样的道理,当数据量非常大的时候,若要从这些数据里找出所有的满足搜索条件的几乎是不太可能的,将会给服务器带来极大的负担。所以我们需要为指定的数据添加一个索引(目录),在这里是为Note创建一个索引,索引的实现细节是我们不需要关心的,至于为它的哪些字段创建索引,怎么指定,正是我要给大家讲的,也是网上所不曾提到的。

每个索引里面必须有且只能有一个字段为 document=True,这代表haystack 和搜索引擎将使用此字段的内容作为索引进行检索(primary field)。其他的字段只是附属的属性,方便调用,并不作为检索数据。直到我自己完成一个搜索器,也没有用到这些附属属性,所以我索性就都删掉了,大家学习的时候也可以先注释掉不管。具体作用我也不明白,反正我没用上。

注意:如果使用一个字段设置了document=True,则一般约定此字段名为text,这是在SearchIndex类里面一贯的命名,以防止后台混乱,当然名字你也可以随便改,不过不建议改。

并且,haystack提供了use_template=True在text字段,这样就允许我们使用数据模板去建立搜索引擎索引的文件,说得通俗点就是索引里面需要存放一些什么东西,例如 Note 的 title 字段,这样我们可以通过 title 内容来检索 Note 数据了,举个例子,假如你搜索 python ,那么就可以检索出含有title含有 python 的Note了,怎么样是不是很简单?数据模板的路径为templates/search/indexes/yourapp/note_text.txt(推荐在项目根目录创建一个templates,并在settings.py里为其引入,使得django会从这个templates里寻找模板,当然,只要放在任何一个你的Django能搜索到的tempaltes下面就好,关于这点我想不属于我们讨论的范畴),templates/search/indexes/blog/note_text.txt文件名必须为要索引的类名_text.txt,其内容为
---------------------

{{ object.title }}
{{ object.user.get_full_name }}
{{ object.body }}

这个数据模板的作用是对Note.titleNote.user.get_full_name,Note.body这三个字段建立索引,当检索的时候会对这三个字段做全文检索匹配。上面已经解释清楚了。

5.在URL配置中添加SearchView,并配置模板

urls.py中配置如下url信息,当然url路由可以随意写。

(r'^search/', include('haystack.urls')),

 其实haystack.urls的内容为

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

SearchView()视图函数默认使用的html模板路径为templates/search/search.html(再说一次推荐在根目录创建templates,并在settings.py里设置好)
所以需要在templates/search/下添加search.html文件,内容为
---------------------

    <h2>Search</h2>

    <form method="get" action=".">
<table>
{{ form.as_table }}
<tr>
<td> </td>
<td>
<input type="submit" value="Search">
</td>
</tr>
</table> {% if query %}
<h3>Results</h3> {% for result in page.object_list %}
<p>
<a href="{{ result.object.get_absolute_url }}">{{ result.object.title }}</a>
</p>
{% empty %}
<p>No results found.</p>
{% endfor %} {% if page.has_previous or page.has_next %}
<div>
{% if page.has_previous %}<a href="?q={{ query }}&page={{ page.previous_page_number }}">{% endif %}« Previous{% if page.has_previous %}</a>{% endif %}
|
{% if page.has_next %}<a href="?q={{ query }}&page={{ page.next_page_number }}">{% endif %}Next »{% if page.has_next %}</a>{% endif %}
</div>
{% endif %}
{% else %}
{# Show some example queries to run, maybe query syntax, something else? #}
{% endif %}
</form>

  

很明显,它自带了分页。
然后为大家解释一下这个文件。首先可以看到模板里使用了的变量有 form,query,page 。下面一个个的说一下。

form,很明显,它和django里的form类是差不多的,可以渲染出一个搜索的表单,相信用过Django的Form都知道,所以也不多说了,不明白的可以去看Django文档,当然其实我倒最后也没用上,最后是自己写了个<form></form>,提供正确的参数如name="seach",method="get"以及你的action地址就OK了。。。如果需要用到更多的搜索功能如过滤的话可能就要自定义Form类了(而且通过上面的例子可以看到,默认的form也是提供一个简单的过滤器的,可以供你选择哪些model是需要检索的,如果一个都不勾的话默认全部搜索,当然我们也是可以自己利用html来模拟这个form的,所以想要实现model过滤还是很简单的,只要模拟一下这个Form的内容就好了),只有这样haystack才能够构造出相应的Form对象来进行检索,其实和django的Form是一样的,Form有一个自我检查数据是否合法的功能,haystack也一样,关于这个此篇文章不做多说,因为我也不太明白(2333)。具体细节去看文档,而且文档上关于View&Form那一节还是比较通俗易懂的,词汇量要求也不是很高,反正就连我都看懂了一些。。。

query嘛,就是我们搜索的字符串。

关于page,可以看到page有object_list属性,它是一个list,里面包含了第一页所要展示的model对象集合,那么list里面到底有多少个呢?我们想要自己控制个数怎么办呢?不用担心,haystack为我们提供了一个接口。我们只要在settings.py里设置:

#设置每页显示的数目,默认为20,可以自己修改
HAYSTACK_SEARCH_RESULTS_PER_PAGE = 8

 

然后关于分页的部分,大家看名字应该也能看懂吧。
如果想要知道更多的默认context带的变量,可以自己看看源码views.py里的SearchView类视图,相信都能看懂。

那么问题来了。对于一个search页面来说,我们肯定会需要用到更多自定义的 context 内容,那么这下该怎么办呢?最初我想到的办法便是修改haystack源码,为其添加上更多的 context 内容,你们是不是也有过和我一样的想法呢?但是这样做即笨拙又愚蠢,我们不仅需要注意各种环境,依赖关系,而且当服务器主机发生变化时,难道我们还要把 haystack 也复制过去不成?这样太愚蠢了!突然,我想到既然我不能修改源码,难道我还不能复用源码吗?之后,我用看了一下官方文档,正如我所想的,通过继承SeachView来实现重载 context 的内容。官方文档提供了2个版本的SearchView,我最开始用的是新版的,最后出错了,也懒得去找错误是什么引起的了,直接使用的了旧版本的SearchView,只要你下了haystack,2个版本都是给你安装好了的。于是我们在myapp目录下再创建一个search_views.py 文件,位置名字可以自己定,用于写自己的搜索视图,代码实例如下:

from haystack.views import SearchView
from .models import * class MySeachView(SearchView):
def extra_context(self): #重载extra_context来添加额外的context内容
context = super(MySeachView,self).extra_context()
side_list = Topic.objects.filter(kind='major').order_by('add_date')[:8]
context['side_list'] = side_list
return context

然后再修改urls.py将search请求映射到MySearchView:

     url(r'^search/', search_views.MySeachView(), name='haystack_search'),

  

讲完了上下文变量,再让我们来讲一下模板标签,haystack为我们提供了 {% highlight %}和 {% more_like_this %} 2个标签,这里我只为大家详细讲解下 highlight的使用。
你是否也想让自己的检索和百度搜索一样,将匹配到的文字也高亮显示呢? {% highlight %} 为我们提供了这个功能(当然不仅是这个标签,貌似还有一个HighLight类,这个自己看文档去吧,我英语差,看不明白)。

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

大概意思是为 text_block 里的 query 部分添加css_class,html_tag,而max_length 为最终返回长度,相当于 cut ,我看了一下此标签实现源码,默认的html_tag 值为 span ,css_class 值为 highlighted,max_length 值为 200,然后就可以通过CSS来添加效果。如默认时:

span.highlighted {
color: red;
}
# 使用默认值
{% 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" %} # 这里可以限制最终{{ result.summary }}被高亮处理后的长度
{% highlight result.summary with query max_length 40 %}

6 从建立索引

  使用python manage.py rebuild_index或者使用update_index命令 

好,下面运行项目,进入该url搜索一下试试吧。

每次数据库更新后都需要更新索引,所以haystack为大家提供了一个接口,只要在settings.py里设置:

#自动更新索引
HAYSTACK_SIGNAL_PROCESSOR = 'haystack.signals.RealtimeSignalProcessor'

作者:AC_hell
来源:CSDN
原文:https://blog.csdn.net/ac_hell/article/details/52875927
版权声明:本文为博主原创文章,转载请附上博文链接!

django-haystack全文检索的更多相关文章

  1. Django Haystack 全文检索与关键词高亮

    Django Haystack 简介 django-haystack 是一个专门提供搜索功能的 django 第三方应用,它支持 Solr.Elasticsearch.Whoosh.Xapian 等多 ...

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

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

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

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

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

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

  5. Haystack全文检索

    1.什么是Haystack Haystack是django的开源全文搜索框架(全文检索不同于特定字段的模糊查询,使用全文检索的效率更高 ),该框架支持Solr,Elasticsearch(java写的 ...

  6. django之全文检索

    全文检索 全文检索不同于特定字段的模糊查询,使用全文检索的效率更高,并且能够对于中文进行分词处理 haystack:django的一个包,可以方便地对model里面的内容进行索引.搜索,设计为支持wh ...

  7. Haystack--基于Django的全文检索框架

    好文章转载自:https://suguangti.cnblogs.com/p/11167097.html 阅读目录 1.什么是Haystack 2.安装 3.配置 4.处理数据 创建索引 5.设置视图 ...

  8. Haystack全文检索框架

    一.什么是Haystack Haystack是django的开源全文搜索框架(全文检索不同于特定字段的模糊查询,使用全文检索的效率更高 ),该框架支持Solr,Elasticsearch,Whoosh ...

  9. Django haystack+solr搜索引擎部署的坑.

    跟着<<Django by Example>> 一路做下来,到了搭建搜索引擎的步骤 默认的思路是用 obj.objects.filter(body__icontains='fr ...

  10. django haystack

    # coding=utf-8 from haystack import indexes from yw_asset.models import * class AssetIndex(indexes.S ...

随机推荐

  1. oracle学习笔记(六) JDBC使用

    JDBC使用 1. 导包 直接使用IDEA导入依赖包即可 新建一个lib,把jar包放在这里 2. 加载驱动 Class.forName("oracle.jdbc.driver.Oracle ...

  2. 使用 MSIX 打包 DotNetCore 3.0 客户端程序

    如何你希望你的 WPF 程序能够以 Windows 的保护机制保护起来,不被轻易反编译的话,那么这篇文章应该能帮到你. 介绍 MSIX 是微软于去年的 Windows 开发者日峰会 上推出的全新应用打 ...

  3. 自定义修改Anaconda Jupyterlab Home目录

    自定义修改Anaconda Jupyterlab Home目录 最近在使用Anaconda学习数据分析和机器学习,会使用到Jupyter,但是他默认目录是用户的目录,我并没有习惯将项目和资料放在C盘, ...

  4. 深入理解Java中的不可变对象

    深入理解Java中的不可变对象 不可变对象想必大部分朋友都不陌生,大家在平时写代码的过程中100%会使用到不可变对象,比如最常见的String对象.包装器对象等,那么到底为何Java语言要这么设计,真 ...

  5. 【English】五、颜色相关

    一.常见颜色 黑色    black    白色    white    蓝色    blue    橙色    orange    黄色    yellow        灰色    gray   ...

  6. git在本地向远程仓库创建分支

    在本地的仓库种,如果想给upstream创建新分支并关联,需要执行 git push -u/--set-upstream 远程仓库名 远程分支名

  7. 测者的测试技术手册:智能化测试框架EvoSuite的一个坑以及填坑方法

    问题 最近在不断地学习和探索EvoSuite框架的时候,在生产JUnit单元测试框架后,出现如下问题: Exception: Caused by: org.evosuite.runtime.TooMa ...

  8. 该用Python还是SQL?4个案例教你节省时间

    在数据分析行业,对数据提出的每一个问题都可以用多种潜在的语言和工具包来回答.每种语言都有其优势,它们之间也存在着不同的区别.不能否认的是,有些操作用Python执行起来要比SQL更加高效.这篇文章分享 ...

  9. Jar 初步

    前言 jar 是 java 文件中一种文件格式,用于将 .java 文件编译的字节码文件打包成 jar. 给 Java 应用打包 1. 新建一个 java 源文件 package cn.szxy; p ...

  10. IOS以无线方式安装企业内部应用(开发者)

    请先阅读:http://help.apple.com/deployment/ios/#/apda0e3426d7 操作系统:osx yosemite 10.10.5 (14F1509) xcode:V ...