最近改进了项目中的站内搜索的功能,增加了全文索引,提升了搜索速度。因为项目框架是django,所以采用django+haystack+pyelasticsearch+elasticsearch的方式实现。

django作为Web framework,采用MVC设计模式,非常易于开发数据库驱动的网站。

haystack是django的搜索插件,提供一套统一的API,用于驱动搜素引擎创建索引,进行搜素。可适用的搜素引擎包括whoosh,ES,Solr等。

pyelasticsearch主要提供python语言调用elasticsearch的Client类。

elasticsearch是一款开源的分布式搜素引擎,具备高可靠性,支持非常多的企业级搜索用例

本项目采用:

django-1.5.0

haystack-2.0.0

pyelasticsearch-0.5

elasticsearch-1.5.0

笔者在实践过程中发现haystack与pyelasticsearch不同版本下协同工作并不一定能成功,有可能报错:

org.elasticsearch.indics.InvalidTypeNameException:mapping type name [_mapping] can't start with '_'

这是haystack创建索引过程中,传入了pyelasticsearch无法解析的dict,通过搜索和尝试,基本确定了上面的版本在Windows7操作系统下能够正常工作。

环境的安装去配置不再累述,用pip命令进行安装非常简单,网上也有很多例子。

进行搜索之前,必须针对数据库视图创建索引,要支持全文搜索,必须对除主键外的字段,特别是类似summary, comment, destription之类的字段创建索引。

haystack创建索引有其固有的格式:

首先,为欲搜索的model创建索引类,这个索引类用于haystack创建索引文件,也用于搜索过程中haystack API进行搜索。

class IncidentIndex(indexes.SearchIndex, indexes.Indexable):
text = indexes.CharField(document=True,use_template=True)
incident_number = indexes.CharField(model_attr='incident_number')
incident_summary = indexes.CharField(model_attr='summary',null=True)
notes = indexes.NgramField(model_attr='notes',null=True)
reported_date = indexes.DateTimeField(model_attr='reported_date') def get_model(self):
return Incident def index_queryset(self, using=None):
"""Used when the entire index for model is updated."""
return self.get_model().objects.all()  

实例代码是项目中为Incidnet model创建索引类的实现:

索引类要继承 indexes.SearchIndex, indexes.Indexable 类,这样索引类就能够像Django的Model类一样提交到后端。

每一个索引类必须至少包含一个document=True的字段以支持基于文件的查找,而这个字段也是search engine主要查找的字段。

Search Field有很多种,常用的CharField,BooleanFeild, DateFeild,IntergeFeild, NgramField,EdgeNgramField在Haystack官网上都有详细的介绍。重点强调一点,如果想输入的词组作为固定的短语进行查询,则字段用CharFeild,如果想输入的词组分词为每个独立的单词进行查询,则字段用NgramField。

null=True用于在创建索引的过程中忽略记录为空的情况。

index_queryset方法用于返回实际的类对象。

创建好索引类之后,要在templates/search/indexs/{AppName}/路径下创建对应索引类的{classname}_text.txt文件,对应索引类中text字段的查询内容。

例如,incident_text.txt:

{{ object.incident_number }}
{{ object.incident_summary }}

用于基于文件的快速检索。

在创建好索引类和相应的基于文件检索的txt文件之后,可以通过manage.py调用haystack的命令创建索引,此时保证elasticsearch是打开的,并且处于默认的进程号9200。

打开ES:click elasticsearch\bin\elasticsearch.bat

创建索引:python manage.py rebuild_index

如果model类更新了,则需要更新索引,可采用命令:python manage.py update_index

需要指出,haystack提供了一种实时自动更新索引的方法,即在索引类定义时,用indexes.RealTimeSearchIndex类代替indexes.SearchIndex,但是更新索引是比较耗时的,并不建议涉及大量用户的网站使用该方法。

创建索引成功之后,就可以在项目中通过调用haystack提供的方法实现search了。

haystack提供了强大的API,用于实现查询,而且API的使用与django API非常相似。主要包括SearchQuerySet API, SearchResult API, SearchQuery API, Input Types, SearchBackend API和上文提到的SearchField API与SearchIndex API。具体使用参见haystack,本文仅列举某些常用API。

SearchQuerySet API提供一个类似于django's ORM QuerySet的查询类,同样具有all,filter,exclude等查询方法用于查询索引。

e.g.

results = SearchQuerySet().filter(incident_number=Exact(query)).highlight()

SearchQuery API 提供一个SQ对象,类似于django的Q,用于组合查询条件。

e.g.

 results = SearchQuerySet().filter(SQ(incident_summary=Exact(query)) | SQ(change_summary=Exact(query)) | SQ(wo_summary=Exact(query)) | SQ(task_summary=Exact(query)) ).highlight()

Input Types允许developer指定一个advance的查询条件,比如:

Exact:确保输入的短语Exactly matched。

Clean: 确保特殊字符的输入能够得到正确的解释,比如url中:和/的escape

-------------------------------- 分割线 ----------------------------------------

今天在QA环境上部署了一把,QA环境是VM,OS是centos-6.3 , django-1.6.5 .

当使用haystack-2.0.0的时候报错:

'SearchNode' object has no attribute 'start_subtree'

通过把haystack替换成2.1.0版本,解决了这个问题。

在进行查询的时候,又报了错:

Failed to query Elasticsearch using '( OR change_summary:("telephony"))': Non-OK response returned (400): u'SearchPhaseExecutionException[Failed to execute phase [query], all shards failed; 

不知道什么情况,索性把setting配置改为:

HAYSTACK_DEFAULT_OPERATOR = 'AND'

嘿嘿,解决了这个问题。

reference:

http://django-haystack.readthedocs.org/en/latest/

django internal search的更多相关文章

  1. Django中search fields报错:related Field has invalid lookup: icontains

    models.py 文件 # coding:utf8from django.db import models class Book(models.Model):        name = model ...

  2. Total Commander 8.52 Beta 1

    Total Commander 8.52 Beta 1http://www.ghisler.com/852_b1.php 10.08.15 Release Total Commander 8.52 b ...

  3. Java多线程系列--“JUC集合”05之 ConcurrentSkipListMap

    概要 本章对Java.util.concurrent包中的ConcurrentSkipListMap类进行详细的介绍.内容包括:ConcurrentSkipListMap介绍ConcurrentSki ...

  4. (13)odoo翻译

    -------------------更新时间:15:52 2016-09-28 星期三 增加模型名翻译17:26 2016-05-20 星期五17:58 2016-05-17 星期二12:14 20 ...

  5. List<T>对元素的查找。

    要在List<T>中查找特定的元素,可以使用Contains() .IndexOf().LastIndexOf()和BinarySearch()方法.除了 LastIndexOf()是从最 ...

  6. Django admin模块使用search时报错:django.core.exceptions.FieldError: Related Field got invalid lookup: contains

    日志如下: <class 'django.core.handlers.wsgi.WSGIRequest'> ------------registered_admins: {'spaceCl ...

  7. django的前后的结合,search搜索功能案例

    利用django的Q()功能可以很好的展开搜索功能 假设我要做个这样的搜索功能

  8. django restframeowrk filter,search,order

    django-filters非常成熟,并且支持drf,在url中以Get参数的形式体现 filter 通用过滤 1. 基本配置 $ pip install django-filters setting ...

  9. elastic search internal

    Realtime Search with Lucene http://2010.berlinbuzzwords.de/sites/2010.berlinbuzzwords.de/files/busch ...

随机推荐

  1. HDU 5044 (树链剖分+树状数组+点/边改查)

    题目链接: http://acm.hdu.edu.cn/showproblem.php?pid=5044 题目大意:修改链上点,修改链上的边.查询所有点,查询所有边. 解题思路: 2014上海网赛的变 ...

  2. cSS3 伪类:nth-child 的使用方法

    :nth-child是一个非常牛逼的伪类,如果你能很好的理解它就可以用CSS 做出很多非常实用的效果.当我很年轻的时候还使用PHP的i++来实现一些东西,其实CSS 完全可以实现.下面是我总结的一些用 ...

  3. java面试题中常见的关于String类问题总结

    问题1: String s1 = “abc”;String s2 = “abc”;System.out.println(s1 == s2); 这里的结果是true. 由于字符串是常量(内存中创建对象后 ...

  4. iOS应用程序本地化

    一.简介 * 使用本地化功能,可以轻松地将应用程序翻译成多种语言,甚至可以翻译成同一语言的多种方言 * 如果要添加本地化功能,需要为每种支持的语言创建一个子目录,称为”本地化文件夹”,通常使用.lpr ...

  5. iOS开发项目之一 [ 项目流程]

    项目流程 *人员配置 *客户端(iOS工程师,Android工程师) *前端 h5 *后台人员(php,java,net) *提供接口(请求地址.请求参数,请求方式,接口文档) *UI UE * 效果 ...

  6. people 0919

    package liu0919; public class People { private double height;// 身高 private String name;// 名字 private ...

  7. CVE-2014-4113 windows通杀本地提权0day

    这个0day的发现挺有意思的,是老外CrowdStrike 发现的,被老外监测程序发现显示从WEBSHELL使用Win64.exe来提升权限. 原文地址:http://blog.crowdstrike ...

  8. mysql时该如何估算内存的消耗,公式如何计算?

    经常有人问配置mysql时该如何估算内存的消耗.那么该使用什么公式来计算呢? 关心内存怎么使用的原因是可以理解的.如果配置mysql服务器使用太少的内存会导致性能不是最优的;如果配置了太多的内存则会导 ...

  9. [转].net 缩略图方法

    本文转自:http://www.cnblogs.com/promic/archive/2010/04/21/1717190.html private static string strConnect ...

  10. [转]用Linq取CheckBoxList選取項目的值

    本文转自:http://www.dotblogs.com.tw/hatelove/archive/2011/11/17/linq-checkboxlist-items-selected-values. ...