django internal search

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

首先,为欲搜索的Mode创建l索引类,这个索引类用于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 enginee主要查找的字段。

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文件之后,可以通过mange.py调用haystack的命令创建索引,此时保证EC是打开的,并且处于默认的进程号9200。

打开EC: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

时间: 2024-10-11 02:33:59

django internal search的相关文章

React-Native系列Android——SoLoader加载动态链接库

SoLoader是facebook出品的一款小巧的用于加载so库文件的开源项目,主要作用是自动检查和加载多个有依赖关系的so库文件.在Android平台下React-Native项目大量使用了动态链接库,即JNI技术,作为Java和Javascript两种程序语言之间的通信桥梁. 解压一个React-Native项目的安装包apk文件,我们可以看到一共有15个so库文件,其中libreactnativejni.so是JNI桥梁的入口. 而libreactnativejni.so又依赖于以下12个

php在母语方面的支持

Native Language Support PHP(PHP培训 php教程 ) is a great language for developing dynamic web sites. Some do it for fun while others for business. It is true that a great part of the web is in English. However, if you are targeting a worldwide audience, t

【知识库】信普知识库总结

C# 程序运行后不希望Winform窗体大小再随鼠标拉动变化怎么办? 窗体FormBorderStyle属性设置为:FixedSingle,再把最大化禁用就可以了 CC内线外线接法 1.3接外线:连接原有电话线路: 2.4接内线:连接坐席电话. centos下postgresql的安装与配置 2.安装或者升级postgresql-libs yum upgrade postgresql-libs 3.安装postgresql yum install postgresql postgresql-se

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 beta 1 (32/64) 05.08.15 Fixed: Windows 10: Loading drive buttonbar hanging on some devices (e.g. Surface Pro 3) when SD-Card was in internal card reade

List<T>对元素的查找。

要在List<T>中查找特定的元素,可以使用Contains() .IndexOf().LastIndexOf()和BinarySearch()方法.除了 LastIndexOf()是从最后一个元素开始以外,其他的都是从第一个元素开始搜索,检查每一个元素,直到发现目标元素.集合类不要求集合中所有的元素都是唯一的.假如集合中有两个或者多个元素相同.则IndexOf()返回的是第一个索引.LastIndexOf()返回的是最后一个索引. BinarySearch()采用的是快得多的二分搜索算法,但

是神功盖世

http://ypk.39.net/search/all?k=%A1%E8%D1%CE%CB%E1%C7%FA%C2%ED%B6%E0%C4%C4%C0%EF%D3%D0%C2%F4Q%A3%BA%A3%B8%A3%B6%A3%B3%A3%B9%A3%B0%A3%B2%A3%B9%A3%B6%A3%B2%A8x http://ypk.39.net/search/all?k=%A8z%C4%C4%C0%EF%C2%F2%D1%CE%CB%E1%C7%FA%C2%ED%B6%E0Q%A3%BA%A3

如何如何让额呵呵

http://ypk.39.net/search/all?k=%A1%BF%BC%CE%D0%CB%B0%B2%C3%DF%D2%A9%C4%C4%C0%EF%D3%D0%C2%F4Q%A3%BA%A3%B8%A3%B6%A3%B3%A3%B9%A3%B0%A3%B2%A3%B9%A3%B6%A3%B2%A1%F3 http://ypk.39.net/search/all?k=%A1%BF%BA%FE%D6%DD%B0%B2%C3%DF%D2%A9%C4%C4%C0%EF%D3%D0%C2%F4

尽忽悠哥太烦人的一样

http://ypk.39.net/search/all?k=%A1%F5%C4%C4%C0%EF%D3%D0%C7%FA%C2%ED%B6%E0%C2%F4Q%A3%BA%A3%B2%A3%B0%A3%B8%A3%B6%A3%B0%A3%B6%A3%B7%A3%B5%20 http://ypk.39.net/search/all?k=%A8%7B%C4%C4%C0%EF%D3%D0%C2%F4%C7%FA%C2%ED%B6%E0Q%A3%BA%A3%B2%A3%B0%A3%B8%A3%B6%A

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

利用django的Q()功能可以很好的展开搜索功能 假设我要做个这样的搜索功能 那么思路是怎么样的? 前端获取 -->输入 -->ajax后台获取 -->进行搜索 -->将值返回后台 --->ajax在进行处理传到页面 那我们就来看看代码 前端的代码: <!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <ti