Django的全文检索

Stella981
• 阅读 277

我们曾经愉快的使用Haystack+Whoosh作为全文检索引擎,可伴随着数据的增加,我们毫无意外的遇到了性能问题。检索时间从毫秒级一下子跌入秒级,常常一个检所需要数秒钟才能返回。而且一旦我们要对索引内容进行调整,而不得不全部重建索引,只能等待数个小时才能建好。

为了解决这个问题,我们考察了众多的方案,并最终决定使用xapain替换Whoosh。

考察过的方案/产品包括:

  • ElasticSearch 非常流行的全文搜索引擎方案。结合Kibbna、Logstash,不但可以实现我们想要的高性能全文检索功能,还能集中采集化日志处理,数据挖掘、分析等。这些也是我们非常想要的功能。放弃原因是,我们的团队规模尚小,且技术领域主要集中于Python和前端。引入ElasticSearch需要很多Java(运维)相关的技能,虽说不是完全陌生,对我们来说也是引入了较高的复杂度。
  • SphinxSearch 看了很多资料。据说性能不错,但是内存占用极大。可靠性不是特别高。
  • Xapain 性能出众,索引数据库小。不支持中文分词,可集成Jieba等第三方分词库。不支持多进程同时写入。

为此我们在xapain-haystack基础上,做了一些改进。增加中文分词,以及串行写入问题。

https://github.com/yuanxu/xapian-haystack

安装和配置

xapian-haystack提供了一个脚本,可以快速安装xapain以及Python-bindings。不过此脚本要求必须使用virtualenv环境。如果未使用请自行修改脚本。

source <path>/bin/activate
./install_xapian.sh 1.4.5

在settings.py中增加如下内容。

HAYSTACK_CONNECTIONS = {
    'default': {
        'ENGINE': 'extension.backends.haystack.xapian_backend.XapianEngine',
        'PATH': os.path.join(BASE_DIR, 'xapian_index'),
    },
}
HAYSTACK_SIGNAL_PROCESSOR = 'extension.backends.haystack.queued_signal.QueuedSignalProcessor'

添加中文支持

我们在Xapain-Haystack基础上,为其增加了中文支持,并改进数值型多关键字检索。

实时更新缓存

Xapain支持一写多读,不支持多个进程同时写入。只能使用Haystack提供的 manage.py rebuild_index周期性的更新索引库,这就造成数据的不一致性。 而我们有一个场景是将全文检索库,作为数据搜索的来源。有一定的时效性要求。 为此,我们借助redis的锁机制,以及Celery实现了串行化索引处理功能。

点赞
收藏
评论区
推荐文章
blmius blmius
2年前
MySQL:[Err] 1292 - Incorrect datetime value: ‘0000-00-00 00:00:00‘ for column ‘CREATE_TIME‘ at row 1
文章目录问题用navicat导入数据时,报错:原因这是因为当前的MySQL不支持datetime为0的情况。解决修改sql\mode:sql\mode:SQLMode定义了MySQL应支持的SQL语法、数据校验等,这样可以更容易地在不同的环境中使用MySQL。全局s
Karen110 Karen110
2年前
一篇文章带你了解JavaScript日期
日期对象允许您使用日期(年、月、日、小时、分钟、秒和毫秒)。一、JavaScript的日期格式一个JavaScript日期可以写为一个字符串:ThuFeb02201909:59:51GMT0800(中国标准时间)或者是一个数字:1486000791164写数字的日期,指定的毫秒数自1970年1月1日00:00:00到现在。1\.显示日期使用
Jacquelyn38 Jacquelyn38
2年前
2020年前端实用代码段,为你的工作保驾护航
有空的时候,自己总结了几个代码段,在开发中也经常使用,谢谢。1、使用解构获取json数据let jsonData  id: 1,status: "OK",data: 'a', 'b';let  id, status, data: number   jsonData;console.log(id, status, number )
皕杰报表之UUID
​在我们用皕杰报表工具设计填报报表时,如何在新增行里自动增加id呢?能新增整数排序id吗?目前可以在新增行里自动增加id,但只能用uuid函数增加UUID编码,不能新增整数排序id。uuid函数说明:获取一个UUID,可以在填报表中用来创建数据ID语法:uuid()或uuid(sep)参数说明:sep布尔值,生成的uuid中是否包含分隔符'',缺省为
Wesley13 Wesley13
2年前
Java日期时间API系列31
  时间戳是指格林威治时间1970年01月01日00时00分00秒起至现在的总毫秒数,是所有时间的基础,其他时间可以通过时间戳转换得到。Java中本来已经有相关获取时间戳的方法,Java8后增加新的类Instant等专用于处理时间戳问题。 1获取时间戳的方法和性能对比1.1获取时间戳方法Java8以前
Easter79 Easter79
2年前
Twitter的分布式自增ID算法snowflake (Java版)
概述分布式系统中,有一些需要使用全局唯一ID的场景,这种时候为了防止ID冲突可以使用36位的UUID,但是UUID有一些缺点,首先他相对比较长,另外UUID一般是无序的。有些时候我们希望能使用一种简单一些的ID,并且希望ID能够按照时间有序生成。而twitter的snowflake解决了这种需求,最初Twitter把存储系统从MySQL迁移
Stella981 Stella981
2年前
Django中Admin中的一些参数配置
设置在列表中显示的字段,id为django模型默认的主键list_display('id','name','sex','profession','email','qq','phone','status','create_time')设置在列表可编辑字段list_editable
Stella981 Stella981
2年前
Net Core使用Lucene.Net和盘古分词器 实现全文检索
Lucene.netLucene.net是Lucene的.net移植版本,是一个开源的全文检索引擎开发包,即它不是一个完整的全文检索引擎,而是一个全文检索引擎的架构,提供了完整的查询引擎和索引引擎,是一个高性能、可伸缩的文本搜索引擎库。它的功能就是负责将文本数据按照某种分词算法进行切词,分词后的结果存储在索引库中,从索引库检索数据的
Wesley13 Wesley13
2年前
MySQL部分从库上面因为大量的临时表tmp_table造成慢查询
背景描述Time:20190124T00:08:14.70572408:00User@Host:@Id:Schema:sentrymetaLast_errno:0Killed:0Query_time:0.315758Lock_
Python进阶者 Python进阶者
1个月前
Excel中这日期老是出来00:00:00,怎么用Pandas把这个去除
大家好,我是皮皮。一、前言前几天在Python白银交流群【上海新年人】问了一个Pandas数据筛选的问题。问题如下:这日期老是出来00:00:00,怎么把这个去除。二、实现过程后来【论草莓如何成为冻干莓】给了一个思路和代码如下:pd.toexcel之前把这