什么时候 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 从一开始就为公共消费而设计。并且该用例的安全性是内置的。默认情况下,API 密钥会限制搜索请求,而像 租户令牌启用多租户 等高级功能。
使用租户令牌限制对文档的访问权限(查看演示)
6. 扩展限制
将所有数据保留在单个数据库中是有正当理由的。但是,在主数据库中拥有与搜索相关的数据会带来巨大的技术后果。在大型数据集上使用 Postgres 进行全文搜索查询会变得非常昂贵,尤其是在对结果进行排名和计算分面计数时。
单体数据库通常会成为需要扩展的应用程序的瓶颈。当您可以避免时,不要将不必要的与搜索相关的成本添加到此资源中。当构建具有高流量的面向用户的应用程序时,这些成本只会成倍增加。
与关系数据库不同,像 Meilisearch 这样的全文搜索引擎使用倒排索引。这种数据结构会创建信息冗余以允许更快地检索信息。它旨在执行搜索操作,并且在大型数据集上自然会优于关系数据库。并且,当搜索使用量激增时,只有一个服务需要扩展。
7. 相关性
正如我们前面提到的,相关的搜索需要拼写错误容忍、自定义排名和同义词。在现代应用程序中,用户希望结果在每次按键时都更新,这需要 前缀搜索。但是 Postgres 全文搜索 ts_rank
函数只允许属性加权。当使用 pg_trgm
扩展时,开发人员需要根据相似性实现自己的排序。
在以搜索为中心的数据库中,结果排名、属性优先级、匹配的单词数量以及查询的精确性是首要概念。它们匹配高级 API,允许对搜索行为进行显式微调。这使得非技术业务利益相关者更容易理解这些概念。这被认为是 Bookshop 选择 Meilisearch 作为其电子商务搜索的关键原因。
8. 错过 InstantSearch 库
在搜索体验方面,网站和应用程序通常实现相同的用户界面模式:文本搜索栏、多面选择的复选框列表、范围滑块、排序菜单、页面导航等。开源的 InstantSearch 库以 JavaScript、iOS 和 Android SDK 中可用的部件形式提供了所有这些功能的实现。
当上市时间至关重要时,很难拒绝这种便利。在 Algolia 的支持下,InstantSearch 库得到了广泛采用,并且一些搜索引擎数据库带有 与 InstantSearch 兼容的 API。阅读我们的 Nuxt 电子商务搜索指南,了解 如何使用 Vue 实现 InstantSearch 部件。> 偏好 React?阅读我们关于 将 InstantSearch 与 React 一起使用 的教程。</Callout>
9. 云支持有限
在云时代,外包服务器的配置、维护和扩展是一种常见的策略。团队可以专注于为用户交付价值,而不是管理服务器。Postgres 与其他数据库一样,在各种云产品中以托管服务的形式提供。不幸的是,托管服务通常会受到限制。
对于 Postgres,实现最先进的全文搜索需要安装扩展。此外,微调语言字典和更多配置需要访问文件系统。不幸的是,这意味着许多功能在云环境中不可用。
为了实现基础设施的委托,搜索引擎通常带有 专用云服务。这些定制平台不会妥协,允许使用完整的搜索功能。此外,客户还可以受益于根据其搜索用例量身定制的优质 SLA、支持和其他企业服务。
Postgres 是一个非常棒且灵活的数据库,可以实现许多自定义的一体化解决方案。它的全文搜索功能可能足以满足基本搜索,但在涉及具有相关性考虑的实时搜索时则显得不足。这些限制在大型数据集上会变得更糟。这是很自然的,因为 Postgres 是一个数据库,而不是搜索引擎。
Meilisearch 是一个开源搜索引擎,旨在构建快速且相关的搜索体验。它的目标是为最终用户提供最先进的体验,同时提供简单直观的开发者体验。您可以尝试 在本地运行 Meilisearch 或 在 Meilisearch Cloud 上免费创建一个帐户。
了解有关 Meilisearch 可以为您的业务带来什么的更多信息
要了解有关 Meilisearch 的更多信息,您可以加入 Discord 上的社区,或订阅 新闻通讯。您可以通过查看 路线图 并参与 产品讨论 来了解有关该产品的更多信息。