把搜索引擎装进数据库:Timescale 发布 pg_textsearch,Postgres 想少依赖一点 Elasticsearch 了

数据库又一次“越界”了,这次盯上的是全文检索
PostgreSQL 这些年的扩张速度,有点像一个原本只想安静做关系型数据库的老实人,后来发现自己被用户不断拉去兼职:时序数据、向量检索、地理空间、流处理……现在,它又把手伸向了更像 Elasticsearch 和 Lucene 地盘的全文搜索。
Timescale 最近开源的 pg_textsearch,就是这么一个信号明确的产品:它试图把现代相关性排序的全文检索,直接塞进 Postgres 里,而且不是停留在“能搜”的程度,而是朝着“搜得像样、排得靠谱、性能还能打”的方向推进。这个扩展已经来到 v1.0.0,并且官方明确说它已经可以用于生产环境。对很多已经把业务压在 Postgres 上的团队来说,这消息相当有诱惑力。
它的核心卖点很直白:支持 BM25 排序,也就是搜索引擎世界里非常经典、非常实用的一套相关性评分机制。你可以直接用类似 ORDER BY content <@> 'search terms' 这样的语法做排序检索,而不是在应用层手搓一堆“标题命中加 3 分、正文命中加 1 分”的土办法。更现实一点说,这意味着 Postgres 的全文检索,不再只是“数据库附赠功能”,而是开始认真追求搜索体验本身。
这件事为什么重要?因为过去很多团队在做站内搜索、知识库搜索、商品描述搜索时,常常会陷入一个熟悉的架构困境:数据库负责存储,Elasticsearch 负责检索,中间还得做同步链路、处理数据延迟、应对索引重建、排查双写不一致。系统一旦长大,搜索就变成那个最容易在半夜把人叫醒的子系统之一。pg_textsearch 想解决的,正是这类“为了搜索不得不再养一套系统”的烦恼。
BM25 进入 Postgres,不只是功能补齐,而是体验升级
如果只看产品介绍,pg_textsearch 像是在给 Postgres 增加一个新索引类型:USING bm25(content)。但从技术路线看,它做的不只是“支持一下 BM25”。这个扩展把 Postgres 原生的文本处理配置也接了进来,英文、法文、德文等语言配置都能用,参数里还能调 k1 和 b,这让它既保留了数据库世界的统一性,又借来了搜索引擎的成熟经验。
这点很关键。很多团队对数据库内建搜索不满意,不是因为它不能查,而是因为排出来的结果“不像人话”。搜索这件事,说到底不是判断命中,而是判断谁更相关。BM25 之所以流行,就是因为它在一个并不花哨的框架下,平衡了词频、文档长度和语料统计,几十年下来依然是很多搜索系统的主力。Timescale 把这套能力装进 Postgres,相当于在告诉开发者:你不一定非得上一个独立搜索集群,才能做出还不错的相关性排序。
更有意思的是,它还引入了 Block-Max WAND 优化,针对 ORDER BY ... LIMIT n 这种 Top-K 查询进行加速。这是典型的搜索引擎思路:既然用户只想看前 10 条,就没必要老老实实把所有候选文档都算一遍分。这个优化听起来学术,但在真实业务里很接地气——新闻站、帮助中心、商品库、日志检索,几乎都在干这件事。一个数据库扩展开始认真做 Top-K 检索优化,本身就说明它想扮演的角色,不再是“凑合能用”的辅助组件。
当然,Postgres 这里也有一点“别扭但务实”的实现细节。由于 PostgreSQL 在某些索引扫描上偏向 ASC 排序,<@> 返回的是负的 BM25 分数,也就是“数值越小,匹配越好”。这有点反直觉,但问题不大,属于数据库工程师会耸耸肩接受的那种现实:能跑、能快、能稳定,形式上的优雅可以往后排。
它在挑战谁?不是要干掉 Elasticsearch,而是在改写中间市场
看到“Postgres 内全文检索”这类消息,很多人第一反应会是:那 Elasticsearch 要凉了吗?我觉得远没到这个程度。更准确的说法是,pg_textsearch 可能会重新切走一大片原本“勉强也得上 ES”的中间市场。
独立搜索系统当然有它不可替代的价值。比如复杂查询语法、短语查询、高亮、聚合分析、大规模分布式检索、多租户搜索平台能力,这些依然是 Lucene/Elasticsearch 生态更成熟。pg_textsearch 自己也很坦率地承认了限制:它不存词项位置,所以原生不支持短语查询,像 "database system" 这种精确短语匹配没法直接优雅实现,只能靠 BM25 先召回、再做后过滤。这在一些对搜索表达能力要求高的场景里,会是明显短板。
但问题是,现实中的大量业务,并不需要那么重的搜索系统。内部文档库、博客文章、工单、商品说明、FAQ、SaaS 后台里的对象搜索,很多时候真正想要的只是:结果别太傻、速度别太慢、运维别太折腾。过去这类需求常常因为“相关性要求比 SQL LIKE 高一点”,就被架构师一脚踢给 Elasticsearch。现在,pg_textsearch 提供了一个更克制的选择:如果你的数据本来就在 Postgres,业务规模也没有大到必须上独立搜索集群,那完全可以先在库内解决。
这其实也是近几年数据库行业的一条暗线。无论是 pgvector 带来的向量检索热,还是各种 JSON、时序、全文能力不断内建,本质上都在推动一个趋势:把更多“足够好”的检索能力搬回数据库,让开发团队少维护一条数据同步链路。数据库正在从“数据存放处”变成“数据工作台”。pg_textsearch 正是这个趋势在文本搜索领域的一次典型落子。
工程味很浓:它真正打动人的,是“别给我添运维负担”
从记者视角看,这个项目最让我有好感的地方,不是 BM25 本身,而是它明显考虑了工程现场的麻烦事。
比如它支持并行建索引,适配大表和分区表;有 memtable 架构来提升写入效率;索引分段支持压缩;批量导入之后还能像 Lucene 一样做 force merge 来整理 segment,减少查询时需要扫描的段数。你能看出来,这不是一个停留在论文气息里的“搜索算法 Demo”,而是在认真处理“线上表很大、数据会持续写入、索引要建得动、查得稳”这些问题。
它还把很多性能行为明明白白摊开给开发者看。比如如果没有 LIMIT,Top-K 优化就没法充分发挥,系统会退回去给更多候选文档打分;如果过滤条件不够选择性,预过滤和后过滤的取舍会直接影响性能和召回;并行建索引需要足够的 maintenance_work_mem,否则会悄悄退回串行模式。这些说明不性感,却特别像成熟基础设施该有的样子:不吹万能,只告诉你什么时候快,什么时候会慢,以及为什么。
还有一个小细节也挺有意思。这个项目原名叫 Tapir,意为 “Textual Analysis for Postgres Information Retrieval”,现在虽然改名成 pg_textsearch,但还保留了貘做吉祥物。数据库扩展圈子里很少有真正“出圈”的角色设计,但一个可爱的吉祥物,确实能让原本硬邦邦的基础设施项目显得没那么冷。技术世界需要这种一点点轻松感,不然每天不是 WAL、就是 vacuum,再不来只貘,大家都快活成索引页了。
真正的问题:数据库到底该长到多胖?
pg_textsearch 的出现,也把一个老争论重新摆到了台面上:数据库是不是正在变成“什么都能做”的巨无霸?
支持者会说,这正是现代开发最需要的整合能力。数据已经在 Postgres 里,再把搜索搬进来,事务一致性更简单,架构更收敛,团队的人力也能集中。尤其在 AI 时代,大家已经习惯在同一个系统里同时做结构化查询、向量召回、元数据过滤、文本排序,多一种原生能力,就少一层胶水代码。今天很多公司真正稀缺的,不是服务器,而是能把多套系统一起伺候好的工程师。
反对者则会担心,数据库承担的职责越多,系统复杂度也会越高。向量检索、全文搜索、时序压缩、流式处理都塞进同一个核心系统,听起来高效,但也意味着更重的资源竞争、更难的调优,以及更高的故障影响面。把“一个系统搞定一切”想得太美,最后也可能演变成“一个系统出问题,全线跟着抖”。
我的看法偏中间:pg_textsearch 不是要替代专业搜索引擎,而是在给数据库用户一个新的分界点。未来很多团队可能会先问一句:这个搜索需求,真的值得为它单独引入 Elasticsearch 吗?如果答案是否定的,那么 Postgres 内建或扩展化的搜索能力就会越来越有吸引力。技术选型从来不是比谁更强,而是比谁“够用且省心”。在这件事上,pg_textsearch 击中的恰恰是当下企业最敏感的神经。
我也很想看它接下来的路线图。如果未来补上更丰富的查询表达、高亮、字段级权重、甚至与向量检索做更自然的混合排序,那它对开发者的吸引力会进一步上升。尤其是在 RAG 和企业知识库应用爆发的今天,关键词检索从来没有过时,反而越来越像向量搜索的搭档。很多人这两年重新意识到:只靠 embedding 不够,经典倒排和 BM25 仍然是检索系统里最稳的骨架之一。
这也是 pg_textsearch 最值得关注的地方。它不是在复古,而是在提醒行业:新技术热潮再大,搜索的基本功依旧重要。而这套基本功,未必要永远寄居在另一个集群里。