Postgres 何时不再适合全文搜索?
本文概述了 Postgres 全文搜索与专注于搜索的数据库相比,在九个方面存在的不足之处。

全文搜索是指将部分或全部文本查询与数据库中存储的文档进行匹配。与传统数据库查询相比,全文搜索即使在部分匹配的情况下也能提供结果。它允许为用户构建更灵活的搜索界面,从而使他们能够更快地找到准确的结果。
从简单的应用内搜索到浏览庞大的电子商务目录,全文搜索的用例数不胜数。它非常普遍,以至于 Postgres 和其他关系型数据库都包含了专门的全文搜索 API。然而,不幸的是,Postgres 在多个方面不如专注于搜索的数据库。
1. 复杂设置
为了提供相关结果,全文搜索应该能够容忍拼写错误、支持同义词和部分匹配。此外,结果排名需要高度可定制,以适应业务的特定需求。在 Postgres 上配置全文搜索需要付出全面的配置成本,并且通常需要在使用托管云服务时无法使用的扩展。
创建数据库索引、编写查询和排名算法很快就会超出领域知识范畴,需要搜索、索引和语言学方面的专业知识。当需要处理旨在弥补 Postgres 全文搜索限制的混合搭配扩展的约束时,性能优化变得更加困难。
相反,专注于搜索的数据库开箱即用地提供了最先进的功能,如拼写容错、前缀搜索、模糊匹配、同义词和可定制的排名。
2. 分面搜索
分面搜索允许用户按广泛的类别来细化搜索结果。它常用于电子商务应用中。例如,一家服装店可以实现按品牌、尺寸或评分范围等分面进行筛选。
电子商务网站上的分面搜索(查看演示)
对于单个分面来说,实现过滤已经足够棘手了。但分面可以有多种形式:类别标签、价格范围或最低评分。为所有类型实现过滤非常具有挑战性。无论如何,最难实现的查询是聚合结果以构建分面计数。这在大型数据集上会变得非常耗费资源。
使用 Postgres 实现分面搜索的复杂性随分面数量的增加呈指数级增长。仅分面搜索本身就是 Elasticsearch 或 Meilisearch 等搜索引擎的一个强大卖点,它们提供优化的、一流的 API 来处理分面过滤和计数。
3. 拼写容错
默认情况下,Postgres 全文搜索无法处理拼写错误。用户通常会安装 pg_trgm
扩展来解决这个限制。(同样,这个解决方案在托管 Postgres 中并非总是可用。)这个扩展显著地引入了新的操作符来比较字符串之间的相似性,以及搜索优化的 GIN 和 GIST 索引。
新的索引允许全文搜索进行更多配置,但在 GIN 和 GIST 索引之间进行选择并非总是简单的事情。此外,新的操作符不考虑单词临近度、空格分隔符或单词大小。这尤其使得用 Postgres 难以实现真正的模糊匹配。
理想情况下,专注于搜索的数据库应该允许为单字查询和多字查询配置不同的规则。Meilisearch 就是这样,它允许完全禁用特定字段的拼写容错。这使得用户可以通过唯一的标识符(如书籍的《国际标准书号》(ISBN))进行搜索。
ISBN 字段已禁用拼写容错(查看演示)
4. 语言支持
使用拉丁字母的语言与阿拉伯语或中文等其他语言之间,语言特性差异很大。截至 Postgres 15,全文搜索字典不适用于简体中文、繁体中文、韩语和日语等语言。这意味着需要为不同的语言采用特定的实现方式。
要查看 Postgres 全文搜索支持的语言列表,您可以在 Postgres 中运行 \dFd
命令。
在 Amazon RDS 等托管环境中,语言支持限制被放大,因为用户无法访问文件系统。这种受限的访问阻止了他们实现自定义字典、词干提取器、同义词等功能。
Meilisearch 除了支持所有使用空格分隔单词的语言外,还为中文、日文、韩文、希伯来语等提供了优化的语言支持。
得益于其充满活力的开源社区,Meilisearch 受益于母语使用者的贡献,以改进特定语言的功能
5. 支付后端成本
Postgres 是一个旨在与服务器端语言通信的数据库。当构建面向公众的客户端应用程序时,这意味着需要在数据库之上构建一个 API 来与客户端通信。除了额外的开发时间之外,创建这样的代理还会带来更多问题。
首先是延迟问题:向在返回结果之前查询数据库的 API 发出请求必然需要一些时间。这不会影响专用的搜索引擎,因为它们带有旨在向最终用户传递数据的公共 API。
现在是第二个问题:安全性。搜索引擎 API 从一开始就设计用于公共消费。并且安全功能已内置以适应该用例。默认情况下,API 密钥会限制搜索请求,而像租户令牌这样的高级功能支持多租户。
使用租户令牌限制对文档的访问(查看演示)
6. 扩展限制
将所有数据保存在单个数据库中有一个合理的动机。但将搜索相关数据保存在主数据库中会带来巨大的技术后果。在大型数据集上进行 Postgres 全文搜索查询变得代价高昂,尤其是在对结果进行排名和计算分面计数时。
单体数据库通常成为需要扩展的应用程序的瓶颈。在可以避免的情况下,不要给这个资源增加不必要的搜索相关成本。当构建面向用户的高流量应用程序时,这些成本只会成倍增加。
与关系型数据库不同,像Meilisearch 这样的全文搜索引擎使用倒排索引,这种数据结构创建信息冗余,以便更快地检索信息。它旨在执行搜索操作,在大型数据集上自然会优于关系型数据库。而且,当搜索使用量激增时,只需扩展单个服务即可。
7. 相关性
正如我们之前提到的,相关搜索需要拼写容错、自定义排名和同义词。在现代应用程序中,用户期望结果在每次击键时更新,这需要前缀搜索。但是 Postgres 全文搜索的 ts_rank
函数只允许属性加权。当使用 pg_trgm
扩展时,开发者只能基于相似性实现自己的排序。
在专注于搜索的数据库中,结果排名、属性优先级、匹配词数和查询精确度都是一流的概念。它们与允许明确微调搜索行为的高级 API 相匹配。这使得将这些概念提供给非技术业务利益相关者变得更容易。这被引述为 Bookshop 选择 Meilisearch进行其电子商务搜索的关键原因。
8. 错过 InstantSearch 库
在搜索体验方面,网站和应用程序通常实现相同的用户界面模式:文本搜索栏、分面复选框列表、范围滑块、排序菜单、页面导航等。开源的 InstantSearch 库以小部件的形式提供了所有这些功能的实现,可通过 JavaScript、iOS 和 Android 的 SDK 获得。
当上市时间至关重要时,很难放弃这些便利。InstantSearch 库得到 Algolia 的支持,享有广泛采用,并且一些搜索引擎数据库提供了兼容 InstantSearch 的 API。阅读我们的 Nuxt 电子商务搜索指南,了解如何使用 Vue 实现 InstantSearch 小部件Callout> 更喜欢 React?阅读我们关于使用 InstantSearch 和 React 的教程。/Callout>
9. 有限的云支持
在云时代,外包服务器的配置、维护和扩展是一种常见策略。团队可以专注于为用户提供价值,而不是管理服务器。Postgres 与其他数据库一样,在广泛的云服务提供商中以托管服务的形式可用。不幸的是,托管服务通常伴随着限制。
就 Postgres 而言,实现最先进的全文搜索需要安装扩展。此外,微调语言字典和更多配置需要访问文件系统。不幸的是,这意味着许多功能在云环境中不可用。
为了实现基础设施的委托管理,搜索引擎通常提供专用云服务。这些定制平台不会妥协,并允许使用全部的搜索功能。此外,客户可以从高级 SLA、支持和其他根据其搜索用例量身定制的企业服务中受益。
Postgres 是一个出色的、灵活的数据库,允许实现许多自定义的、一体化解决方案。它的全文搜索功能对于基本搜索可能已经足够,但涉及到实时搜索和相关性问题时就显得不足。这些限制在大型数据集上会变得更加严重。这很自然,因为 Postgres 是一个数据库,而不是搜索引擎。
Meilisearch 是一个开源搜索引擎,旨在构建快速且相关的搜索体验。它致力于为最终用户提供最先进的体验,同时提供简单直观的开发者体验。您可以通过在本地运行 Meilisearch 或在 Meilisearch Cloud 免费创建账户来试用它。
了解 Meilisearch 能为您的业务带来什么
有关 Meilisearch 的更多信息,您可以加入 Discord 社区或订阅新闻通讯。您可以通过查看路线图并参与产品讨论来了解更多关于产品的信息。