社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Django

使用django和postgres进行全文检索

Python程序员 • 6 年前 • 480 次点击  

这些天我需要一个全文检索。这个方面的佼佼者是Elastic Search和Sorl:它们快速、灵活、资源消耗量大,而且需要java,而我创建的这个小项目几乎所有东西就运行在一个5美元的DigitalOcean droplet中。


在放弃了这些选项之后,我只剩下了Xapian和postgres全文检索,虽然Xapian的功能似乎更丰富,但我决定从postgres开始,因为它与django进行了原生集成,并且我对这个特定项目的要求也不高。


项目及需求


你可能已经注意到了,我在运营一个招聘网站。Voorjob基本上是从lever.co聚合职位并让用户通过它进行搜索。目前我的数据库中有大约25000个职位,这个数字增长的很缓慢,每增加2或3个职位,就会有另一个职位被关闭。所以,是的,如果我在这个数据库上采用了弹性搜索路径,那它将会是一个教科书般的过度设计情景。


实现


由于9.4版本的postgres增加了一些允许全文检索的特性。不久之后,Django就在其postgres特定特性中支持了这些特性。


要开始使用这个新特性,首先我需要在我的模型中增加一个SearchVectorField,还需要一些方法来使用向量化的职位描述更新这个字段:



这种方法对于某些很少更新的东西很适用,比如一个招聘网站,但如果你的应用程序经常更新,你应该避免这种策略,并使用一些能周期性地填充该向量的任务:



或者更好的是,通过阅读这个文档,你可以直接使用一个postgres触发器来完成。


职位查询


既然你已经准备好了你的数据库,是时候查询它了,我们来看看voorjob搜索视图的说教版本:



我在这里主要考虑两种查询:单词出现和“精确表达式”。是的,这种逻辑有一些缺陷,去起诉我吧:D


这个视图还有很多地方需要改进,django支持加权查询:


这将最终以一个更好的顺序返回结果,其中标题中的匹配将比正文中的匹配提供更多的权重。


这个查询系统也更加灵活,它允许逻辑操作OR/AND和NOT。在不久的将来,我将改进我的招聘网站的搜索,并更新本文来描述其中的变化。


性能


在开发过程中,我使用了一个带有16GB内存和一个不错的NVMe固态硬盘的I5。在我的本地机器上对25000个职位运行查询基本上是瞬间完成的。


当我把这个项目投入生产时(在那个5美元的droplet中),事情变得越来越慢。


运行时间基准测试,我得到以下结果:


  • 在/路径下检索"django rest framework"  ( 扫描5000个条目花费1秒钟 )

  • 在/full路径下检索"django rest framework"  (扫描25000个条目花费3秒种 )


虽然性能不是最佳,但至少现在还可以。本文将继续进行更新,以展示任何性能改进。


考虑到我的检索需求不太大——总单词数不超过本文的25000个条目——使用postgres作为我的全文检索后端对这个早期阶段的MVP来说刚刚好。现在,我更感兴趣的是尝试一些新东西并增加这个网站的观众,而不是给予我的20个日常用户世界上最快的体验。


更新 (2020年2月9日)


好消息!我得知我可以向我的SearchVectorField添加一个索引:



现在各种情形的检索时间都降到了1秒钟。由于我的数据很小,所以这个索引使用的内存可以忽略不计。


英文原文:http://voorloopnul.com/blog/full-text-search-with-django-and-postgres/ 
译者:忧郁的红秋裤

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/54993