| 注册
请输入搜索内容

热门搜索

Java Linux MySQL PHP JavaScript Hibernate jQuery Nginx
gww3
10年前发布

利用PostgreSQL实现毫秒级全文检索

原文  http://www.infoq.com/cn/news/2015/05/PostgreSQL-Lateral-Max


Lateral 是一家内容推荐服务提供商,其 模拟程序 使用 PostgreSQL 存储文档。每个文档包含一个text列和一个存储标题、日期和URL等元数据的JSON列。他们希望为模拟程序创建快速搜索功能,搜索文档全文和标题,生成推荐内容。近日,Lateral首席技术官Max 撰文 介绍了他们的做法。

为了实现这一目标,可以选择开源解决方案 Apache SolrElasticsearch ,也可以选择托管解决方案 ElasticAlgolia ,但出于以下考虑,他们选择了 PostgreSQL的全文搜索功能

  • 不需要额外安装软件或库
  • 可以重用他们在应用程序中使用的数据库接口
  • 不需要配置额外的服务器
  • 不增加成本
  • 数据可以存储在可控的地方
  • 不需要在不同的数据源之间同步数据

虽然PostgreSQL搜索的精度和 大规模查询速度存在缺陷 ,但Max认为,它可以满足他们的应用场景。以下是他们的做法:

  1. 创建一个列tsv,存储tsvector值;
  2. 在新建的列上创建索引,并用下面的语句填充列:

    UPDATE data_rows SET tsv  =setweight(to_tsvector(coalesce(meta->>'title','')), 'A')   ||setweight(to_tsvector(coalesce(text,'')), 'D');

    此处需要注意,JSON列的权重为A,text列的权重为D;

  3. 创建tsv列更新函数;
  4. 在表上创建触发器,当更新和新增行时,执行tsv列更新函数。

当一切就绪后,替换下面代码中的“你的查询”并执行:

SELECT id, meta->>'title' as title, meta FROM (    SELECT id, meta, tsv    FROM data_rows, plainto_tsquery('你的查询') AS q    WHERE (tsv @@ q)  ) AS t1 ORDER BY ts_rank_cd(t1.tsv, plainto_tsquery('你的查询')) DESC LIMIT 5;

经测试,该查询大约50毫秒即可完成。如果返回文档全文,则会增加大约350毫秒,这更多的可能是受网络负载影响。如果只返回文档中的200个字符,则仅仅增加大约100毫秒。

 本文由用户 gww3 自行上传分享,仅供网友学习交流。所有权归原作者,若您的权利被侵害,请联系管理员。
 转载本站原创文章,请注明出处,并保留原始链接、图片水印。
 本站是一个以用户分享为主的开源技术平台,欢迎各类分享!
 本文地址:https://www.open-open.com/lib/view/open1431572854919.html
PostgreSQL 数据库服务器