Postgres不适合用于全文搜索的几种场景

与以搜索为中心的数据库相比,Postgres 全文搜索存在不足的九个领域的概述。

什么是全文搜索?
全文搜索是指将部分或全部文本查询与数据库中存储的文档进行匹配。与传统的数据库查询相比,全文搜索即使在部分匹配的情况下也能提供结果。它允许为用户构建更灵活的搜索界面,从而使他们能够更快地找到准确的结果。

从简单的应用内搜索到浏览庞大的电子商务目录,全文搜索用例非常多。Postgres 和其他关系数据库包含用于全文搜索的专用 API 是很常见的。不幸的是,Postgres 在多个领域都缺乏以搜索为中心的数据库。

1.复杂的设置
为提供相关结果,全文搜索应允许错别字、同义词和部分匹配。此外,结果排序需要高度可定制,以适应企业的特定需求。在 Postgres 上配置全文搜索需要进行全面的配置,而且往往需要使用扩展功能,而这些功能在使用托管云服务时无法使用。

创建数据库索引、编写查询和排名算法很快就会超出领域知识的范围,需要搜索、索引和语言学方面的专业知识。如果为了应对 Postgres 全文搜索的限制而使用混合匹配的扩展,那么优化性能就会变得更加困难。

相反,以搜索为重点的数据库则具有最先进的功能,如错字容忍、前缀搜索、模糊匹配、同义词和开箱即用的自定义排名。

2.分面搜索
分面搜索Faceted search 允许用户按大类细化搜索结果。它通常用于电子商务应用中。例如,服装店可以按品牌、尺码或等级范围等方面进行筛选。

对于单个面来说,实施过滤已经够麻烦了。但是,面可以有多种形式:类别标签、价格范围或最低评级。针对所有类型实施过滤非常具有挑战性。无论如何,最难实现的查询是聚合结果以建立面计数。在大型数据集上,这将耗费大量资源。

使用 Postgres 实施切面搜索的复杂性随着切面数量的增加而呈指数增长。分面搜索本身就是 Elasticsearch 等搜索引擎的一大卖点。它们配备了优化的一流应用程序接口,可以处理面过滤和计数。

3.错字容忍度
默认情况下,Postgres 全文搜索无法处理拼写错误。用户通常会安装 pg_trgm 扩展来绕过这一限制(同样,在托管的 Postgres 中也不一定有这一解决方案)。(该扩展主要引入了新的操作符,用于比较字符串之间的相似性,以及搜索优化的 GIN 和 GIST 索引。

新索引允许对全文搜索进行更多配置,但在 GIN 和 GIST 索引之间做出选择并非总是那么容易。此外,新的运算符不考虑单词邻近度、空格分隔符或单词大小。这尤其使 Postgres 难以实现真正的模糊匹配。

理想情况下,以搜索为重点的数据库应该允许为单词查询和多词查询配置不同的规则。允许完全禁用特定字段的错别字。

4.语言支持
使用拉丁字母的语言与阿拉伯语或中文等其他语言之间的语言特点差异很大。从 Postgres 15 开始,简体中文、繁体中文、韩文和日文等语言都无法使用全文检索词典。这就意味着要针对不同的语言采用特定的实现方法。

在用户无法访问文件系统的 Amazon RDS 等托管环境中,语言支持限制更为严重。这种访问限制使用户无法实施自定义字典、词干、同义词等。

5.增加后台成本
Postgres 是一种用于与服务器端语言通信的数据库。在构建面向公众的客户端应用程序时,这意味着要在数据库之上构建一个应用程序接口(API),以便与客户端通信。除了额外的开发时间外,创建这样一个代理还会带来更多问题。

首先是延迟问题:向查询数据库的应用程序接口发出请求,然后再返回结果,这必然会花费一些时间。这不会影响专用搜索引擎,因为它们带有公共 API,旨在向最终用户提供数据。

现在是第二个问题:安全性。搜索引擎 API 从一开始就是为公共消费而设计的。安全问题也是针对这种使用情况而设计的。默认情况下,API 密钥会限制搜索请求,而租户令牌等高级功能则可实现多租户。

6.扩展限制
将所有数据保存在一个数据库中的动机是合理的。但在主数据库中保存搜索相关数据会带来很大的技术问题。使用 Postgres 对大型数据集进行全文搜索查询成本很高,尤其是在对结果进行排序和计算面计数时。

单体数据库往往会成为需要扩展的应用程序的瓶颈。在可以避免的情况下,不要给这种资源增加不必要的搜索相关成本。在构建面向用户的高流量应用程序时,这些成本只会成倍增加。

与关系数据库不同,全文搜索引擎使用的是倒排索引:这种数据结构会产生信息冗余,从而加快信息检索速度。它专为执行搜索操作而设计,在大型数据集上的表现自然优于关系数据库。而且,当搜索使用量激增时,只需扩展一项服务即可。

7.相关性
正如我们前面提到的,相关搜索需要错字容忍度、自定义排名和同义词。在现代应用中,用户希望每次按键都能更新结果,这就需要使用前缀搜索。但 Postgres 全文搜索 ts_rank 函数只允许属性加权。在使用 pg_trgm 扩展时,开发人员只能自己根据相似度实现排序。

在以搜索为重点的数据库中,结果排序、属性优先级、匹配字数和查询精确度等概念都是一流的概念。它们与允许对搜索行为进行明确微调的高级应用程序接口相匹配。这使得向非技术、业务利益相关者提供这些概念变得更加容易。

结论
Postgres 是一个优秀、灵活的数据库,允许实施许多定制的一体化解决方案。它的全文搜索功能可能足以满足基本搜索的需要,但在涉及相关性问题的实时搜索时,它就显得力不从心了。在大型数据集上,这些限制会变得更加严重。这很正常,因为 Postgres 是一个数据库,而不是搜索引擎。

PostgreSQL 是一个强大的关系型数据库管理系统,但并不是在所有情况下都适用于全文搜索。以下是九种情景,其中 PostgreSQL 可能不是最佳选择,特别是在需要强大全文搜索功能的场景下:

  1. 大规模文本数据: 当文本数据非常庞大时,PostgreSQL 的全文搜索性能可能不如专门的全文搜索引擎,例如 Elasticsearch。全文搜索引擎专注于处理大量文本数据,提供更高效的检索和分析能力。
  2. 实时搜索需求: 对于需要实时搜索的应用,如实时日志分析或监控系统,专门的实时搜索引擎通常更适合,因为它们能够提供更低的搜索延迟。
  3. 复杂的搜索需求: 如果你的应用需要执行复杂的全文搜索查询,涉及到文本分析、语义搜索或相关性排序等高级搜索功能,全文搜索引擎通常更为灵活。
  4. 分布式搜索: 对于分布式环境下的大规模搜索需求,全文搜索引擎能更好地处理分布式数据存储和搜索索引的问题,而 PostgreSQL 在这方面的支持相对有限。
  5. 实时推荐系统: 在需要实时生成和推送推荐结果的场景下,全文搜索引擎通常能更好地满足实时性的要求。
  6. 大规模并发写入: 如果应用场景下有大规模的并发写入需求,而搜索操作又频繁,可能需要考虑专门的搜索引擎,以免影响数据库写入性能。
  7. 多语言全文搜索: PostgreSQL 在全文搜索方面对多语言支持较为有限,对于需要处理多语言文本的应用,全文搜索引擎通常更具优势。
  8. 高度定制的搜索需求: 在需要高度定制搜索行为的场景下,全文搜索引擎提供了更多的配置选项和扩展性,以满足特定的搜索需求。
  9. 大规模文档存储: 如果应用场景主要是大规模文档的存储和检索,全文搜索引擎可能更适合处理大量的非结构化文档。

总体而言,PostgreSQL 在一般性的全文搜索场景下表现良好,但在某些特殊需求下,使用专门的全文搜索引擎可能更为合适。