微信扫码
添加专属顾问
我要投稿
AI搜索迎来新变革,混合搜索三大流派谁主沉浮? 核心内容: 1. 混合搜索三大技术流派原理与差异解析 2. 各流派在"大海捞针"场景中的实战表现对比 3. 国产数据库在混合索引领域的技术突破
向量搜索已过时,没听错,因为AI搜索不等于向量搜索,相关性不等于相似性!很早以前我有过相关分享:别被“资本炒作”带坑里了!AI搜索!=向量搜索、相关性!=相似性
AI 领域真正需要的是相关性,也就是经常说的混合搜索是啥?
需求很明确, 实现方法确各不相同, 性能差异也很大! 我把他总结成了3个流派, 大家觉得哪个更有前途呢?
下面我用大海捞针的场景来进行比喻.
1、第一个流派(技术实现难度最低): 硬搜, 每个条件各自建立索引, 各自搜索找出N条(这样能用到各个索引), 最后JOIN得到都满足条件的. 再进行综合排名, 返回排名靠前的若干条!
这个方法不是不行, 但是当多个查询的结果相交后没有记录怎么办? 或者记录条数太少, 无法满足业务要的条数怎么办? 再扩大每个查询的LIMIT数, 再来一遍? 显然效率会比较差!
大海捞针时, 几个打捞团队, 每个打捞团队都给出了方圆10公里的打捞范围, 针落在他们的交集里, 但是也可能没有交集, 此时所有打捞队伍都扩大搜索半径, 总能打捞到.
2、第二个流派: 向量和标量的混合索引(技术实现难度最高). 我最近分享过一篇 《VexDB HybridAnn 向量标量混合索引原理与实践》 , 这家国产厂商不得了,把向量和标量做到了一个联合索引里面去, 向量和标量可同时使用索引检索快速的收敛到小部分满足条件的结果集. 效率高. 刚好上周末参加了海量数据的1024专家闭门讨论会,他们最新发布的的Vastbase V100也是这么做的!具体实现原理可参考上面的文章!里面提到了为什么这个流派的技术实现难度最高,以及存在哪些潜在挑战!
谁敢说国产数据库不行,人家已经技术上领先了好吧!
大海捞针时, 精准定位到针在哪里, 直接进行打捞, 效率最高. 但是也要符合前提条件(也就是索引和搜索条件一致), 不是所有的条件都能精准打捞, 不满足前提条件的时候可能退化为第一流派的方法.
3、第三个流派: 混合权重(技术实现难度一般)
流派三的好处是每个条件都可以使用到各自的索引, 也许是一种新思路!
你觉得哪种流派最有前景呢?
你用过的向量数据库属于什么流派呢? 来说说吧。
例如 Milvus、VastBase V100, VexDB, Oceanbase、pgvector ...
我先表达一下个人观点: 我目前站第二流派和第三流派结合, 可能是同时能满足精度、效率、技术门槛低的..
下面让我们看看来自 ParadeDB 的这篇文章(https://www.paradedb.com/blog/hybrid-search-in-postgresql-the-missing-manual), 了解一下第三流派的玩法!
PostgreSQL 的搜索能力远超大多数开发者的认知。许多人一遇到搜索需求就转向 Elasticsearch 这样的外部搜索引擎,或 Pinecone 这类专用向量数据库,但实际上 PostgreSQL 本身就能提供相同的功能——你只需要知道哪些扩展能释放它的潜力。
ParadeDB 为 PostgreSQL 带来了可用于生产环境的全文搜索,支持基于 BM25 的词法相关性评分;而 pgvector 则提供向量相似度计算,实现语义理解。但如何将二者结合成一个混合系统呢?
这就是 PostgreSQL 混合搜索的缺失手册。
我们将一步步构建一个完整的解决方案,将词法精确性与语义理解相结合,并使用“倒数排名融合”(Reciprocal Rank Fusion, RRF)生成既准确又有意义的排序结果。最终,你将拥有一套完全运行在数据库内部、无需外部依赖、也无需同步烦恼的生产级搜索策略。
在深入混合搜索之前,我们先直面一个显而易见的问题:PostgreSQL 本身就内置了全文搜索功能,为什么不直接用它?
PostgreSQL 原生的全文搜索(基于 tsvector 和 tsquery)对于基础文本匹配确实可用,但它有一个根本性局限——一旦你开始对结果排序,问题就暴露出来了。其排序函数(如 ts_rank)仅孤立地评估单个文档,无法理解整个语料库的全局统计信息。
这在实践中意味着什么?当 ts_rank 看到某文档中“PostgreSQL”出现了三次,它会认为该文档比只出现一次的更相关。这在局部看是合理的。但它无法判断“PostgreSQL”是一个常见词(出现在 80% 的文档中),还是一个稀有且具有区分度的词(仅出现在 5% 的文档中)。
这看似简单,但正是这种缺乏全局上下文的特性,构成了基础文本搜索与现代相关性排序之间的根本区别。
这就是 BM25 登场的原因。BM25 由信息检索领域的研究者提出,专门用于解决上述全局上下文问题。它正是几乎所有现代搜索引擎(包括 Elasticsearch 和 Solr)背后的核心算法。
BM25 通过结合三个智能信号来解决排序问题:
虽然有多种方式将 BM25 引入 PostgreSQL(也有从 PostgreSQL 调用外部搜索引擎的方法),但最简单且性能最佳的方案是使用 ParadeDB 的 pg_search 扩展。
ParadeDB 将生产级 BM25 直接作为原生索引类型集成进 PostgreSQL,无需外部搜索系统的运维复杂性。
使用 ParadeDB 非常简单。安装扩展后,你可以像创建其他 PostgreSQL 索引一样创建 BM25 索引,并通过简洁的操作符语法进行查询。
要将 pg_search 添加到你的 PostgreSQL 实例(或通过 Docker 启动一个新实例),请参阅我们的部署指南。
CREATE EXTENSION pg_search IFNOTEXISTS;
CREATETABLE documents (
idSERIAL PRIMARY KEY,
title TEXT,
contentTEXT
);
-- 使用英文分词器并启用词干提取,创建 BM25 索引
CREATEINDEX idx_documents_bm25 ON documents
USING bm25 (
id,
title::pdb.simple('stemmer=english'),
content::pdb.simple('stemmer=english')
)
WITH (key_field=id);
-- 对标题或内容中包含“postgresql”或“search”的文档进行 BM25 相关性排序
-- 标题匹配权重提升 2 倍(因其更可能相关)
SELECTid, title, pdb.score(id) AS bm25_score
FROM documents
WHERE
title ||| 'postgresql search'::boost(2) OR
content ||| 'postgresql search'
ORDERBY bm25_score DESC;
上面的 ||| 操作符用于“或”匹配(disjunction),但还有许多其他选项可用。与、短语匹配、高亮、相似文档推荐(more like this)、正则表达式查询、词距(word proximity)等均受支持。ParadeDB 在查询优化方面也很智能:它能尽可能将 WHERE 条件和分面聚合(faceting aggregations)下推到 BM25 索引中,使复杂的带过滤搜索比传统方法快得多。
这种词法搜索擅长精确或近似匹配:当用户搜索特定术语、产品编码或他们已知名称的技术概念时(或相近词,详见我们关于分词与词干提取的博客),它表现极佳。
但 BM25 有一个根本性局限。当用户搜索“database performance optimization”(数据库性能优化)时,BM25 无法找到仅包含“PostgreSQL tuning”(PostgreSQL 调优)或“query optimization”(查询优化)的文档,尽管这些文档可能正是用户所需。这时,我们就需要混合搜索的第二块拼图。
向量搜索通过处理“含义”而非“词语”来解决语义理解问题。BM25 将“postgresql”和“database”视为完全不同的词,而向量搜索则理解它们在概念上是相关的。
魔法来自嵌入模型(embedding models)——这些 AI 网络经过训练,能将文本转换为高维向量(通常为 768、1024 或 1536 维)。这些向量有一个奇妙的特性:语义相近的概念在向量空间中彼此靠近。“PostgreSQL”和“database”的嵌入会很相似,“performance”和“optimization”也是如此。
PostgreSQL 不会自动生成嵌入。你需要使用外部嵌入模型(如 OpenAI 的 text-embedding-ada-002 或开源替代方案)创建向量,并将其存储到数据库中。这可以在插入文档时完成,也可以通过批量更新现有内容实现。
这意味着,即使文档不包含你的确切搜索词,向量搜索也能找到相关结果。搜索“database speed improvements”(数据库速度提升),你可能会找到关于“PostgreSQL performance tuning”(PostgreSQL 性能调优)或“query optimization techniques”(查询优化技巧)的文档——这是词法搜索完全无法做到的。
过去,在 PostgreSQL 中实现向量搜索需要依赖外部向量数据库或复杂的自定义方案。但 pgvector 扩展改变了这一点,它将向量操作直接引入 PostgreSQL。就像 ParadeDB 之于 BM25,pgvector 使向量搜索成为 PostgreSQL 的一等公民,具备优化的索引和距离操作符。
要在现有的 documents 表中添加向量搜索功能,需要安装 pgvector,添加一个用于存储嵌入的向量列,并为相似度查询创建索引。
要将 pgvector 添加到你的 PostgreSQL 实例,请参阅其安装说明。如果你使用 ParadeDB 的 Docker 镜像,pgvector 已预装并可直接使用。
-- 启用 pgvector
CREATE EXTENSION vector IFNOTEXISTS;
-- 添加嵌入列
ALTERTABLE documents ADDCOLUMN embedding vector(1536);
-- 创建向量索引
CREATEINDEX idx_documents_vector ON documents
USING hnsw (embedding vector_cosine_ops);
-- 按相似度搜索
-- 向量是你查询文本的向量表示,需在应用中生成
SELECT
id,
title,
1 - (embedding <=> '[0.1,0.2,...]'::vector) AS similarity
FROM documents
ORDERBY similarity DESC;
向量搜索在语义相似性方面表现出色,能发现词法搜索遗漏的概念关联。但这一优势也是其弱点。向量搜索以精确性换取理解力。
当用户搜索特定产品编码(如“PG-15.4”)或确切技术术语(如“pg_stat_statements”)时,向量搜索可能会返回关于相关但不同概念的文档。嵌入模型无法区分“PostgreSQL 15.4”和“PostgreSQL 14.2”——在向量空间中,它们都只是“PostgreSQL 版本”。
这正是根本权衡所在:BM25 提供精确性但缺乏语义,向量搜索提供语义理解但可能模糊于精确匹配。如果两者兼得呢?
混合搜索结合词法与语义方法,同时获得 BM25 的精确性和向量搜索的语义理解力。但结合两种不同的搜索方法并非易事——你不能简单地将 BM25 分数与向量相似度分数相加,因为它们的量纲完全不同。
这时,“倒数排名融合”(Reciprocal Rank Fusion, RRF)提供了一个优雅的解决方案。RRF 不尝试归一化并合并原始分数,而是聚焦于排名。其核心洞见简洁而深刻:如果一个文档在多个不同搜索系统中都排名靠前,那它很可能非常相关。
RRF 通过一个简单公式将排名转换为分数:
其中 k 是一个常数(通常为 60),用于控制分数随排名下降的速度,rank_i 是文档在第 i 个系统中的排名。在多个系统中排名靠前的文档将获得最高的综合分数。
RRF 的美妙之处在于它与量纲无关。无论你的 BM25 分数范围是 0–10 还是 0–1000,无论你的向量相似度是在 0–1 还是 -1 到 1 之间,RRF 只关心相对排名。这使其极其稳健且易于调优。
WITH
--- 全文搜索,使用 pg_search 和 BM25 排序
fulltext AS (
SELECTid, ROW_NUMBER() OVER (ORDERBY pdb.score(id) DESC) AS r
FROM documents
WHEREcontent ||| 'keyboard'
LIMIT20
),
--- 语义搜索,使用 pgvector 和余弦距离排序
semantic AS (
SELECTid, ROW_NUMBER() OVER (ORDERBY embedding <=> '[1,2,3]') AS r
FROM documents
LIMIT20
),
-- 计算每个排序器的 RRF 贡献
rrf AS (
SELECTid, 1.0 / (60 + r) AS s FROM fulltext
UNIONALL
SELECTid, 1.0 / (60 + r) AS s FROM semantic
)
-- 汇总 RRF 分数,按分数排序,并关联原始数据
SELECT
m.id,
SUM(s) AS score,
m.content
FROM rrf
JOIN documents AS m USING (id)
GROUPBY m.id, m.content
ORDERBY score DESC
LIMIT5;
注意每个排序 CTE 中的 LIMIT 20。RRF 在每个系统仅提供顶级候选结果时效果最佳,而非喂入完整结果集。这使融合聚焦于最有希望的文档,同时保持计算高效。
基础 RRF 实现对两个搜索系统一视同仁,但在实践中,你可能希望强调其中一种方法。也许你的用户倾向于搜索特定技术术语(偏向 BM25),或者他们使用更口语化的查询(偏向向量搜索)。
加权 RRF 允许你通过为每个系统应用不同权重来平衡词法与语义的影响:
rrf AS (
SELECT id, 0.7 * 1.0 / (60 + r) AS s FROM fulltext -- 70% 权重
UNION ALL
SELECT id, 0.3 * 1.0 / (60 + r) AS s FROM semantic -- 30% 权重
)
此配置强调词法匹配而非语义相似性,适用于技术文档场景——用户常搜索特定术语、函数名或错误信息。请根据你的用例和用户行为调整权重。
RRF 最强大的方面之一,是它能自然地扩展到搜索相关性之外。现实世界的搜索系统需要在相关性与业务需求(如热度、新鲜度、用户偏好或内容质量)之间取得平衡。
传统搜索引擎通过复杂的评分函数解决此问题,但这些函数难以调优和调试。RRF 采取不同思路:将每个业务需求视为独立的排序系统,然后将它们全部融合。
想提升热门内容?创建一个基于浏览量的排名。需要突出近期文章?添加一个新鲜度排名。想推广高质量内容?加入编辑评分。RRF 让你能自然地组合这些信号:
--- 基于浏览量的热度排名
popularity AS (
SELECTid, ROW_NUMBER() OVER (ORDERBY view_count DESC) AS r
FROM documents
LIMIT1000
),
--- 基于创建日期的新鲜度排名
recency AS (
SELECTid, ROW_NUMBER() OVER (ORDERBY created_at DESC) AS r
FROM documents
LIMIT1000
),
注意非搜索信号(如热度和新鲜度)使用了更高的限制(1000),而搜索结果限制为 20。非搜索排名无需依赖查询相关的相关性过滤,因此可以容纳更大的候选集。
这种多信号方法赋予你极大的灵活性。你可以按季节调整权重(新闻事件期间提升新鲜度)、按用户类型调整(新用户强调热度,资深用户强调相关性),或按内容类型调整(博客优先新鲜度,文档优先权威性)。
关键洞见在于:每个信号都是独立且可解释的。如果搜索结果过于偏向热门内容,只需降低热度权重;如果近期内容曝光不足,就提高新鲜度权重。无需调试复杂的评分函数,只需直观地调整权重即可。
PostgreSQL 中的混合搜索通过 RRF 融合,将 BM25 的词法精确性与向量嵌入的语义理解相结合。ParadeDB 和 pgvector 使这一切无需外部依赖即可实现——所有内容都在你现有的数据库中运行,享有 ACID 保证和事务一致性。
基于 SQL 的方法意味着你能清晰看到排名如何工作,直观调整权重,并按需添加业务逻辑。没有黑盒算法,也没有需要管理的复杂外部系统。
53AI,企业落地大模型首选服务商
产品:场景落地咨询+大模型应用平台+行业解决方案
承诺:免费POC验证,效果达标后再合作。零风险落地应用大模型,已交付160+中大型企业
2025-10-30
Cursor 2.0的一些有趣的新特性
2025-10-30
Anthropic 发布最新研究:LLM 展现初步自省迹象
2025-10-30
让Agent系统更聪明之前,先让它能被信任
2025-10-30
Rag不行?谷歌DeepMind同款,文档阅读新助手:ReadAgent
2025-10-29
4大阶段,10个步骤,助你高效构建企业级智能体(Agent)
2025-10-29
DocReward:让智能体“写得更专业”的文档奖励模型
2025-10-29
沃尔沃RAG实战:企业级知识库,早就该放弃小分块策略
2025-10-29
大模型的Funcation Calling是什么?
2025-08-21
2025-08-21
2025-08-19
2025-09-16
2025-10-02
2025-09-08
2025-09-17
2025-08-19
2025-09-29
2025-08-20
2025-10-29
2025-10-29
2025-10-28
2025-10-28
2025-10-27
2025-10-26
2025-10-25
2025-10-23