最近改进了项目中的站内搜索的功能,增加了全文索引,提升了搜索速度。因为项目框架是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/

最新文章

  1. 33条C#和.NET经典面试题目及答案
  2. ThinkPHP中简单的CURD操作
  3. CodeForces 705A(训练水题)
  4. Delphi如何打开DBF数据库
  5. Spring 常用工具类
  6. ural 1160
  7. sharepoint的webpart开发
  8. Android 颜色渲染(十) ComposeShader组合渲染
  9. Top k问题(线性时间选择算法)
  10. 编写生成彩色验证码的Servlet
  11. ios7.1 masonry布局中出现的问题
  12. xshell安装运行时提示缺少mfc110.dll
  13. 201521123025 《Java程序设计》第2周学习总结
  14. mysql 先分组在排序
  15. "《算法导论》之‘图’":深度优先搜索、宽度优先搜索(无向图、有向图)
  16. (四) Keras Dropout和正则化的使用
  17. poj-3281(拆点+最大流)
  18. dijkstra 的优先队列优化
  19. [学习笔记]我们追过的神奇异或(Trie树系列)
  20. RedisTemplate 分页

热门文章

  1. BX2001: IE 支持使用 window.clipboardData 访问系统剪贴板,Chrome 和 Safari 中存在类似的 Clipboard 对象但尚未实现,Firefox 和 Opera 不支持这类对象
  2. [Unity2D]精灵动画
  3. new在c#方法中的使用
  4. Linux /etc/passwd 和 /etc/group 文件格式
  5. 《GK101任意波发生器》升级固件发布(版本:1.0.2build955)
  6. XML基础知识
  7. 如何用Apache POI操作Excel文件-----如何对一个单元格加注解?
  8. 如何设置jquery的ajax方法为同步
  9. [ZZ] 景深效果(Depth of Field) , Pass1 将场景渲染到一个RenderTarget,做为清晰版, Pass2: BluredRT , Pass3: WDepth = Depth / Far_Z_Clip
  10. PHP 设计模式 笔记与总结(9)数据对象映射模式