69

我正准备在 Heroku 上部署一个需要全文搜索的 Rails 应用程序。到目前为止,我一直在使用 MySQL 和 Sphinx 的 VPS 上运行它。

但是,如果我想在 Heroku 上使用 Sphinx 或 Solr,我需要付费购买附加组件。

我注意到 PostgreSQL(Heroku 上使用的数据库)具有内置的全文搜索功能。

我不能使用 Postgres 的全文搜索有什么原因吗?它比狮身人面像慢还是有其他一些主要限制?

4

6 回答 6

77

编辑,2016 年 — 为什么不两者兼而有之?

如果您对 Postgres 和 Lucene 感兴趣,为什么不两者兼而有之?查看 Postgres 的ZomboDB扩展,它将 Elasticsearch 集成为一流的索引类型。仍然是一个相当早期的项目,但对我来说它看起来很有希望。

(技术上在 Heroku 上不可用,但仍然值得一看。)


披露:我是WebsolrBonsai Heroku 附加组件的联合创始人,所以我的观点有点偏向 Lucene。

我对 Postgres 全文搜索的了解是,它对于简单的用例来说非常可靠,但是 Lucene(以及因此 Solr 和 ElasticSearch)在性能和功能方面都优越的原因有很多。

对于初学者来说,jpountz为这个问题提供了一个真正优秀的技术答案,为什么 Solr 比 Postgres 快这么多?值得仔细阅读以真正消化。

我还评论了最近 RailsCast 的一集,比较了 Postgres 全文搜索与 Solr 的相对优缺点。让我在这里回顾一下:

Postgres 的实用优势

  • 重用您已经在运行的现有服务,而不是设置和维护(或支付)其他东西。
  • 远远优于极其缓慢的 SQLLIKE运算符。
  • 由于数据都在同一个数据库中,因此保持数据同步的麻烦更少——无需与某些外部数据服务 API 进行应用程序级集成。

Solr(或 ElasticSearch)的优势

在我的脑海中,没有特别的顺序......</p>

  • 将您的索引和搜索负载与常规数据库负载分开扩展。
  • 更灵活的术语分析,​​例如重音规范化、语言词干提取、N-gram、标记删除……其他很酷的功能,例如拼写检查、“丰富内容”(例如 PDF 和 Word)提取……</li>
  • Solr/Lucene 可以很好地完成Postgres 全文搜索 TODO 列表中的所有操作。
  • 更好更快的术语相关性排名,在搜索时有效地定制。
  • 常见术语或复杂查询的搜索性能可能更快。
  • 可能比 Postgres 更有效的索引性能。
  • 通过将索引与主数据存储分离,更好地容忍数据模型的变化

显然,我认为基于 Lucene 的专用搜索引擎是这里更好的选择。基本上,您可以将 Lucene 视为事实上的搜索专业知识的开源存储库。

但是,如果您唯一的其他选择是LIKE运算符,那么 Postgres 全文搜索绝对是一个胜利。

于 2012-06-04T05:38:26.523 回答
22

由于我刚刚将弹性搜索 (1.9) 与 postgres FTS 进行了比较,因此我认为我应该分享我的结果,因为它们比@gustavodiazjaimes 引用的更新一些。

我对 postgres 的主要担心是它没有内置 faceting,但是构建自己很简单,这是我的示例(在 django 中):

results = YourModel.objects.filter(vector_search=query)
facets = (results
    .values('book')
    .annotate(total=Count('book'))
    .order_by('book'))

我正在使用 postgres 9.6 和 elastic-search 1.9(通过 django 上的 haystack)。下面是 elasticsearch 和 postgres 在 16 种不同类型查询中的比较。

    es_times  pg_times  es_times_faceted  pg_times_faceted
0   0.065972  0.000543          0.015538          0.037876
1   0.000292  0.000233          0.005865          0.007130
2   0.000257  0.000229          0.005203          0.002168
3   0.000247  0.000161          0.003052          0.001299
4   0.000276  0.000150          0.002647          0.001167
5   0.000245  0.000151          0.005098          0.001512
6   0.000251  0.000155          0.005317          0.002550
7   0.000331  0.000163          0.005635          0.002202
8   0.000268  0.000168          0.006469          0.002408
9   0.000290  0.000236          0.006167          0.002398
10  0.000364  0.000224          0.005755          0.001846
11  0.000264  0.000182          0.005153          0.001667
12  0.000287  0.000153          0.010218          0.001769
13  0.000264  0.000231          0.005309          0.001586
14  0.000257  0.000195          0.004813          0.001562
15  0.000248  0.000174          0.032146          0.002246
                  count      mean       std       min       25%       50%       75%       max
es_times           16.0  0.004382  0.016424  0.000245  0.000255  0.000266  0.000291  0.065972
pg_times           16.0  0.000209  0.000095  0.000150  0.000160  0.000178  0.000229  0.000543
es_times_faceted   16.0  0.007774  0.007150  0.002647  0.005139  0.005476  0.006242  0.032146
pg_times_faceted   16.0  0.004462  0.009015  0.001167  0.001580  0.002007  0.002400  0.037876

为了让 postgres 达到这些多面搜索的速度,我必须在字段上使用带有 SearchVectorField 的 GIN 索引,这是 django 特有的,但我确信其他框架具有类似的向量类型。

另一个考虑因素是 pg 9.6 现在支持短语匹配,这是巨大的。

我的收获是,在大多数情况下,postgres 会更受欢迎,因为它提供:

  1. 更简单的堆栈
  2. 无需处理搜索后端 api 包装器依赖项(thinking-sphinx、django-sphinx、haystack 等)。这些可能会很麻烦,因为它们可能不支持您的搜索后端所做的功能(例如干草堆分面/聚合)。
  3. 具有相似的性能和功能(满足我的需要)
于 2016-10-04T14:50:32.217 回答
16

我发现了这个惊人的比较并想分享它:

PostgreSQL 中的全文搜索

构建索引 LIKE 谓词的时间 -- 无
PostgreSQL / GIN -- 40 分钟
Sphinx 搜索 -- 6 分钟
Apache Lucene -- 9 分钟
倒排索引 -- 高

索引存储 LIKE 谓词 -- 无
PostgreSQL / GIN -- 532 MB
Sphinx 搜索 -- 533 MB
Apache Lucene -- 1071 MB
倒排索引 -- 101 MB

查询速度 LIKE 谓词 -- 90+ 秒
PostgreSQL / GIN -- 20 毫秒
Sphinx 搜索 -- 8 毫秒
Apache Lucene -- 80 毫秒
倒排索引 -- 40 毫秒

于 2013-05-20T04:06:11.763 回答
3

Postgres 的全文搜索在词干提取、排名/提升、同义词处理、模糊搜索等领域具有惊人的功能——但不支持分面搜索。

因此,如果 Postgres 已经在您的堆栈中并且您不需要分面,那么在寻找基于 Lucene 的解决方案之前,最好先尝试一下,以利用易于保持索引同步和保持流畅堆栈的巨大好处——至少如果全部您的应用不基于搜索。

于 2015-07-13T04:54:21.770 回答
3

合成客户数据(1000 万条记录)的一些更新结果。

在此处输入图像描述

于 2020-02-26T08:14:33.323 回答
1

Postgresql 的 FTS 函数在查找方面非常成熟且相当快。值得一看。

于 2012-06-04T03:50:45.737 回答