
全文搜索是指将文本查询的全部或部分与数据库中存储的文档进行匹配。与传统数据库查询相比,全文搜索即使在部分匹配的情况下也能提供结果。它允许为用户构建更灵活的搜索界面,从而使他们能够更快地找到准确的结果。
从简单的应用内搜索到浏览庞大的电子商务目录,全文搜索的用例数不胜数。它如此常见,以至于 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 获得。
当上市时间至关重要时,很难放弃这些便利。在 Algolia 的支持下,InstantSearch 库获得了广泛采用,并且一些搜索引擎数据库提供了与 InstantSearch 兼容的 API。阅读我们的 Nuxt 电子商务搜索指南,了解如何使用 Vue 实现 InstantSearch 小部件。喜欢 React?阅读我们关于使用 InstantSearch 与 React 的教程。
9. 有限的云支持
在云时代,外包服务器的配置、维护和扩展是一种常见策略。团队可以专注于为用户提供价值,而不是管理服务器。Postgres 与其他数据库一样,在各种云产品中提供托管服务。不幸的是,托管服务通常存在限制。
对于 Postgres 而言,实现最先进的全文搜索需要安装扩展。此外,对语言词典和其他配置进行微调需要访问文件系统。不幸的是,这意味着许多功能在云环境中不可用。
为了支持基础设施的委托管理,搜索引擎通常提供专用云服务。这些定制平台不会妥协,允许使用全套搜索功能。此外,客户可以受益于高级 SLA、支持以及为满足其搜索用例而量身定制的其他企业服务。
Postgres 是一个很棒的、灵活的数据库,可以实现许多自定义的一体化解决方案。它的全文搜索功能可能足以满足基本的搜索需求,但在涉及实时搜索和相关性问题时就显得不足了。这些限制在大型数据集上会变得更加严重。这是很自然的,因为 Postgres 是一个数据库,而不是搜索引擎。
Meilisearch 是一个开源搜索引擎,旨在构建快速且相关的搜索体验。它旨在为最终用户提供最先进的体验,同时提供简单直观的开发体验。您可以通过在本地运行 Meilisearch 或在 Meilisearch Cloud 上免费创建帐户来尝试它。
了解 Meilisearch 能为您的业务带来什么
要了解更多 Meilisearch 相关信息,您可以加入Discord 社区或订阅新闻通讯。您可以通过查看路线图并参与产品讨论来了解更多产品信息。