第三篇Doris混合搜索Hybrid Search文本向量结构化的一体化检索关键字Apache Doris、混合搜索、HSAP、RRF融合、CC加权、BM25、倒排索引、向量检索、预过滤机制、DataMind标签全文检索 | 向量数据库 | 混合搜索 | 搜索引擎 | RRF算法 | 智能检索 | 数据库技术 | 语义搜索一、引言为什么你需要混合搜索在真实的业务场景中用户的搜索需求很少是单一维度的。想象一下你在某电商平台搜索无线降噪耳机你的真实意图可能包括文本匹配商品名或描述中包含无线、“降噪”、耳机这些关键词语义理解想买的是耳机而不是无线鼠标或降噪耳塞业务规则价格在 500-1500 元之间、品牌是小米/华为/苹果、销量排名前 100传统的解决方案是分别调用多个系统然后用代码手动融合结果。这种架构的问题显而易见┌─────────────────────────────────────────────────────────────────┐ │ 传统多系统融合架构 │ │ │ │ 用户查询 │ │ │ │ │ ▼ │ │ ┌────────┐ ┌──────────┐ ┌─────────┐ │ │ │倒排索引│ │向量数据库 │ │ 关系库 │ │ │ │(ES) │ │(Milvus) │ │(MySQL) │ │ │ └───┬────┘ └────┬─────┘ └────┬────┘ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ 关键词分数 语义分数 过滤条件 │ │ │ │ │ │ │ └──────────────┼───────────────┘ │ │ ▼ │ │ 人工融合逻辑权重调参 │ │ │ │ │ ▼ │ │ 最终排序结果 │ └─────────────────────────────────────────────────────────────────┘这套架构存在三个致命缺陷延迟高多次网络调用、一致性差数据可能不同步、运维复杂三套系统需要分别管理。Doris 4.0 的混合搜索Hybrid Search彻底解决了这个问题。它将三种检索能力统一在同一个 SQL 引擎中通过 RRF 和 CC 等融合算法在底层完成了结果融合让用户用一条 SQL 就能实现复杂的多维检索需求。二、混合搜索架构设计2.1 HSAP 模型解析HSAPHybrid Search and Analytics Processing是 Doris 4.0 提出的核心理念。它的核心思想是用户不需要关心数据用什么索引检索系统会自动根据查询特征选择最优的执行路径。┌─────────────────────────────────────────────────────────────────────────┐ │ HSAP 统一执行架构 │ │ │ │ ┌──────────────────────────────────────────────────────────────┐ │ │ │ SQL 解析层 │ │ │ │ ┌────────────────────────────────────────────────────────┐ │ │ │ │ │ 查询优化器自动选择执行路径 │ │ │ │ │ └────────────────────────────────────────────────────────┘ │ │ │ └──────────────────────────────────────────────────────────────┘ │ │ │ │ │ ┌─────────────────────────┼─────────────────────────┐ │ │ │ ▼ │ │ │ │ ┌────────────────┐ ┌────────────────┐ ┌────────────────┐ │ │ │ │ 全文检索引擎 │ │ 向量检索引擎 │ │ 结构化分析引擎 │ │ │ │ │ (倒排索引) │ │ (HNSW) │ │ (列式存储) │ │ │ │ │ │ │ │ │ │ │ │ │ │ BM25 评分 │ │ L2/IP 距离 │ │ B-Tree 索引 │ │ │ │ │ MATCH_ANY │ │ APPROX_COS │ │ Zone Map │ │ │ │ └───────┬────────┘ └───────┬────────┘ └───────┬────────┘ │ │ │ │ │ │ │ │ └──────────┼────────────────────┼────────────────────┼────────────────┘ │ │ │ │ │ ▼ ▼ ▼ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ 文本相似度 │ │ 语义相似度 │ │ 业务规则 │ │ │ (0~1) │ │ (0~1) │ │ (0/1) │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘ │ │ │ │ │ └────────────────────┼────────────────────┘ │ ▼ │ ┌─────────────────┐ │ │ 融合排序层 │ │ │ RRF / CC / 自定义│ │ └────────┬────────┘ │ │ │ ▼ │ ┌─────────────────┐ │ │ TopN 结果集 │ │ └─────────────────┘ └─────────────────────────────────────────────────────────────────────────┘2.2 三路搜索融合机制混合搜索的核心是三路检索的协同工作第一路倒排索引全文检索基于 BM25 算法计算文本相关性评分支持关键词匹配、短语匹配、布尔组合查询使用 INVERTED 索引存储词项-文档映射第二路HNSW 向量索引语义检索基于近似最近邻算法计算语义相似度支持高维向量的高效检索可配置 L2 距离或内积作为度量方式第三路B-Tree/Zone Map结构化索引基于传统数据库索引的条件过滤等值查询、范围查询、IN 查询利用 Doris 的向量化执行引擎进行高效过滤2.3 预过滤与虚拟列下推混合搜索的一个关键技术点是预过滤Pre-filtering机制。在传统的向量数据库中通常的做法是先做向量检索得到 TopK 结果再在结果集上做条件过滤。这种方式的缺点是过滤条件可能筛掉太多候选结果导致召回率下降。Doris 的实现恰恰相反先做结构化过滤再做向量检索。┌─────────────────────────────────────────────────────────────────┐ │ Doris 预过滤执行流程 │ │ │ │ 输入全量数据 1000万条 │ │ │ │ Step 1: 结构化过滤 │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ WHERE category 电子产品 │ │ │ │ WHERE price BETWEEN 100 AND 1000 │ │ │ │ 输出候选集 50万条 │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ │ ▼ │ │ Step 2: 向量检索基于候选集 │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ ORDER BY l2_distance(embedding, query_vec) │ │ │ │ LIMIT 20 │ │ │ │ 输出最终结果 20条 │ │ │ └─────────────────────────────────────────────────────────┘ │ │ │ │ 优势避免在大规模数据上做向量计算性能提升 10x │ └─────────────────────────────────────────────────────────────────┘这种设计的优势是结构化过滤可以快速缩小搜索范围向量计算只在候选集上执行。三、融合排序算法详解3.1 RRFReciprocal Rank FusionRRF 是最简单的融合算法核心思想是基于排名位置而非分数进行融合RRF_score(doc) Σ 1/(k rank_i(doc)) 其中 - k常数因子通常取 60 - rank_i文档在第 i 路检索结果中的排名从 1 开始RRF 的优势是对分数尺度不敏感不同检索通路的分数范围可能差异巨大RRF 只关心排名实现简单只需要知道每路返回的 TopK 列表不需要归一化处理鲁棒性强某个通路异常不会显著影响最终结果RRF 的 SQL 实现WITH-- 第一路文本检索倒排索引text_searchAS(SELECTid,score()AStext_score,1AStext_rankFROMproductsWHEREMATCH_ANY(name,description,无线降噪耳机)LIMIT100),-- 第二路向量检索HNSWvector_searchAS(SELECTid,l2_distance_approximate(embedding,:query_vec)ASvec_score,ROW_NUMBER()OVER(ORDERBYl2_distance_approximate(embedding,:query_vec))ASvec_rankFROMproductsWHEREl2_distance_approximate(embedding,:query_vec)1.0LIMIT100)-- RRF 融合SELECTp.id,p.name,p.price,COALESCE(t.text_rank,0)AStext_rank,COALESCE(v.vec_rank,0)ASvec_rank,COALESCE(1.0/(60t.text_rank),0)COALESCE(1.0/(60v.vec_rank),0)ASrrf_scoreFROMproducts pLEFTJOINtext_search tONp.idt.idLEFTJOINvector_search vONp.idv.idORDERBYrrf_scoreDESCLIMIT20;3.2 CCConvex CombinationCC 是加权求和融合核心思想是为每路检索分配一个固定权重CC_score(doc) Σ w_i * norm_score_i(doc) 其中 - w_i第 i 路检索的权重满足 Σ w_i 1 - norm_score_i归一化后的第 i 路分数CC 的优势是精确控制可以精细地调整各通路的权重比例解释性强最终分数是各通路分数的线性组合易于理解CC 的 SQL 实现WITHtext_scoresAS(SELECTid,score()ASraw_scoreFROMproductsWHEREMATCH_ANY(name,description,无线降噪耳机)),vector_scoresAS(SELECTid,l2_distance_approximate(embedding,:query_vec)ASraw_scoreFROMproducts),normalizedAS(SELECTt.id,-- 归一化文本分数BM25 分数通常在 0-20 范围(t.raw_score-(SELECTMIN(raw_score)FROMtext_scores))/NULLIF((SELECTMAX(raw_score)-MIN(raw_score)FROMtext_scores),0)ASnorm_text,-- 归一化向量分数距离越小越好需要反转1-(v.raw_score-(SELECTMIN(raw_score)FROMvector_scores))/NULLIF((SELECTMAX(raw_score)-MIN(raw_score)FROMvector_scores),0)ASnorm_vecFROMtext_scores tFULLOUTERJOINvector_scores vONt.idv.id)SELECTid,0.6*norm_text0.4*norm_vecASfinal_scoreFROMnormalizedORDERBYfinal_scoreDESC;3.3 融合算法选择指南┌─────────────────────────────────────────────────────────────────┐ │ 融合算法选择决策树 │ │ │ │ 业务场景 │ │ │ │ │ ├─── 是否需要精确控制各通路权重 │ │ │ │ │ │ │ Yes ──→ CC 加权融合 │ │ │ │ │ │ │ No │ │ │ │ │ │ │ ├─── 是否有归一化基准 │ │ │ │ │ │ │ No ──→ RRF 融合推荐 │ │ │ │ │ │ │ Yes ──→ 可以尝试 CC 或 混合策略 │ │ │ │ │ └─── 结果数量是否稳定 │ │ │ │ │ No ──→ RRF 更鲁棒 │ │ │ │ │ Yes ──→ 两者均可 │ └─────────────────────────────────────────────────────────────────┘四、混合查询实战模式4.1 文本过滤 标签过滤 向量 TopN这是最常见的混合搜索场景——结合关键词、分类和向量相似度进行检索SELECTproduct_id,product_name,category,brand,price,sales_count,score()ASbm25_score,l2_distance_approximate(embedding,:query_vec)ASvec_distanceFROMproductsWHERE-- 文本条件MATCH_ANY(product_name,product_desc,无线降噪耳机)-- 分类过滤ANDcategory_id101-- 价格区间ANDpriceBETWEEN200AND2000-- 销量要求首页只需展示有销量的商品ANDsales_count0-- 品牌白名单ANDbrandIN(小米,华为,苹果,索尼,Bose)ORDERBY-- 综合排序文本相关性与语义相似度融合score()*0.4(1-l2_distance_approximate(embedding,:query_vec)/2)*0.6DESC,sales_countDESCLIMIT20;4.2 多路召回融合对于需要高召回率的场景可以使用 UNION ALL 实现多路独立召回WITHresultsAS(-- 第一路文本匹配SELECTid,title,score()AStext_score,1ASsourceFROMarticlesWHEREMATCH_ANY(title,content,:query)LIMIT100UNIONALL-- 第二路向量相似SELECTid,title,1-l2_distance_approximate(embedding,:query_vec)/2AStext_score,2ASsourceFROMarticlesWHEREl2_distance_approximate(embedding,:query_vec)0.8LIMIT100UNIONALL-- 第三路标签相关SELECTid,title,0.5AStext_score,3ASsourceFROMarticlesWHEREarray_contains(tags,:relevant_tag)LIMIT100),rankedAS(SELECTid,title,SUM(text_score)AStotal_score,COUNT(*)ASmatch_sourcesFROMresultsGROUPBYid,title)SELECTid,title,total_score,match_sources,-- 多路命中加权total_score*(10.1*match_sources)ASfinal_scoreFROMrankedORDERBYfinal_scoreDESCLIMIT20;4.3 范围查询与 TopK 融合有时我们需要同时返回完全匹配和语义相似的结果SELECTid,title,CASE-- 精确匹配标题完全包含查询词WHENMATCH_PHRASE(title,:query)THEN1.0-- 关键词匹配包含部分词WHENMATCH_ANY(title,:query)THEN0.8score()/20-- 语义相似向量距离在范围内WHENl2_distance_approximate(embedding,:query_vec)0.3THEN0.7-- 弱语义相似向量距离稍远WHENl2_distance_approximate(embedding,:query_vec)0.6THEN0.5ELSE0.0ENDASrelevance_scoreFROMdocumentsWHEREMATCH_ANY(title,content,:query)ORl2_distance_approximate(embedding,:query_vec)0.8ORDERBYrelevance_scoreDESCLIMIT50;五、字节跳动 DataMind 实践案例5.1 业务背景与挑战DataMind 是字节跳动内部的一站式数据分析平台支持海量日志的实时检索和分析。在引入 Doris 之前平台面临以下挑战多系统并存全文检索用 Elasticsearch向量检索用 Faiss业务查询用 ClickHouse数据同步延迟三个系统之间的数据同步延迟从秒级到分钟级不等维护成本高需要维护三套基础设施三个团队分别负责5.2 基于 Faiss 的 HNSW IVF_PQ 双算法支持DataMind 在 Doris 基础上做了深度定制实现了 Faiss 风格的多种 ANN 算法支持┌─────────────────────────────────────────────────────────────────┐ │ DataMind ANN算法实现架构 │ │ │ │ ┌─────────────────────────────────────────────────────────┐ │ │ │ Faiss 兼容层 │ │ │ │ │ │ │ │ ┌─────────────┐ ┌─────────────┐ │ │ │ │ │ HNSW │ │ IVF_PQ │ ┌─────────────┐│ │ │ │ │ 分层小世界图 │ │ 倒排量化索引 │ │ FLAT ││ │ │ │ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘│ │ │ │ │ │ │ │ │ │ │ └──────────────────┼───────────────────┘ │ │ │ │ ▼ │ │ │ │ ┌─────────────────┐ │ │ │ │ │ 统一索引接口 │ │ │ │ │ └────────┬────────┘ │ │ │ └────────────────────────────┼────────────────────────────┘ │ │ ▼ │ │ ┌─────────────────────┐ │ │ │ Doris 存储引擎 │ │ │ └─────────────────────┘ │ └─────────────────────────────────────────────────────────────────┘HNSW 适用场景对召回率要求极高95%数据规模在亿级以下IVF_PQ 适用场景数据规模极大10亿可以接受一定的召回率损失5.3 Tablet-level BM25 全局统计信息聚合BM25 算法需要计算 IDF逆文档频率这依赖于全局的文档统计信息。在分布式场景下不同 Tablet 的统计信息是隔离的。DataMind 的解决方案是实现Tablet-level 聚合机制-- 伪代码Tablet 级别 BM25 聚合SELECTid,BM25_WITH_GLOBAL_STATS(content,:query,(SELECTCOUNT(*)FROM__global_doc_stats__),(SELECTAVG_DOC_LENFROM__global_doc_stats__),(SELECTDF_TERM(:query)FROM__all_tablets__))ASbm25_scoreFROMdistributed_docsWHEREMATCH_ANY(content,:query)ORDERBYbm25_scoreDESCLIMIT20;5.4 自训练重排序模型集成在粗排之后DataMind 还集成了自研的 Learning to RankLTR模型进行精排┌─────────────────────────────────────────────────────────────────┐ │ 两阶段排序架构 │ │ │ │ Query ──────────┬──────────────┬──────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ │ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ │ │ │ 文本检索 │ │ 向量检索 │ │ 结构化过滤│ │ │ └────┬─────┘ └────┬─────┘ └────┬─────┘ │ │ │ │ │ │ │ └──────────────┼──────────────┘ │ │ ▼ │ │ ┌──────────┐ │ │ │ 粗排 TopK │ K 1000 │ │ └────┬─────┘ │ │ ▼ │ │ ┌────────────────┐ │ │ │ LTR 重排序模型 │ │ │ │ (BERT-based) │ │ │ └───────┬────────┘ │ │ ▼ │ │ 精排 TopK K 20 │ │ │ │ │ ▼ │ │ 最终结果 │ └─────────────────────────────────────────────────────────────────┘六、索引协同机制深度解析6.1 倒排索引与 HNSW 的协同倒排索引和 HNSW 索引可以同时存在互相补充CREATETABLEhybrid_docs(idBIGINTNOTNULL,title STRING,contentTEXT,tags ARRAYSTRING,embedding ARRAYFLOATNOTNULL,-- 倒排索引加速文本匹配INDEXidx_inverted_title(title)USINGINVERTED PROPERTIES(parserstandard),INDEXidx_inverted_content(content)USINGINVERTED PROPERTIES(parserstandard),-- HNSW 索引加速向量检索INDEXidx_hnsw(embedding)USINGANN PROPERTIES(index_typehnsw,metric_typel2_distance,dim768))DUPLICATEKEY(id)DISTRIBUTEDBYHASH(id)BUCKETS16;6.2 IDSelector 机制Doris 的混合搜索使用 IDSelector 在不同索引之间传递候选集-- 执行流程伪代码1.倒排索引扫描 → 得到满足关键词条件的 ID 列表2.将 ID 列表封装为 IDSelector bitmap3.HNSW 检索时使用 IDSelector 过滤只在候选集内检索4.对交集结果进行最终排序这种设计的好处是避免在无关数据上浪费计算资源同时保证多路检索结果的一致性。6.3 暴力计算降级策略当预过滤后的候选集过小时Doris 会自动降级为暴力计算-- 假设经过预过滤只剩 100 条记录-- Doris 会评估HNSW 索引扫描成本 vs 暴力计算成本-- 如果候选集足够小选择暴力计算以获得精确结果SETprefer_brute_force_threshold1000;-- 阈值可调七、性能优化实战7.1 索引构建优化分批构建避免 OOM-- 将大表分成多个小批次构建索引CREATEINDEXidx_hnswONlarge_table(embedding)USINGANNPARTITIONBYHASH(id)PARTITIONS16PROPERTIES(max_degree32,ef_construction40);Compaction 优化-- 在构建索引前先做一次 full compactionALTERTABLEdoc_store COMPACT(full);-- 查看 compaction 进度SHOWPENDING TABLETSWHERETypeBASE;7.2 查询执行优化利用向量化执行-- Doris 默认启用向量化执行SETenable_vectorized_enginetrue;-- 监控向量化执行效率SHOWVARIABLESLIKE%vector%;并行度调整-- 根据机器配置调整并行度SETparallel_fragment_exec_instance_num8;SETmax_execution_time30000;-- 30 秒超时7.3 监控指标关键监控指标┌─────────────────────────────────────────────────────────────────┐ │ 混合搜索关键监控指标 │ │ │ │ 性能指标 │ │ ├── Query Latency P50/P95/P99 │ │ ├── QPS │ │ ├── 索引扫描占比 │ │ └── 各通路耗时占比 │ │ │ │ 质量指标 │ │ ├── 召回率通过人工标注集评估 │ │ ├── 点击率/转化率 │ │ └── RRF/CC 融合得分分布 │ │ │ │ 资源指标 │ │ ├── 内存使用率 │ │ ├── CPU 利用率 │ │ └── 索引命中率 │ └─────────────────────────────────────────────────────────────────┘八、常见问题与解决方案8.1 融合结果不如预期症状RRF 融合后某些相关文档被遗漏。排查检查各通路单独召回的结果确认 k 参数是否合适k 太小会导致排名权重过高考虑调整 RRF k 值或改用 CC 加权-- 尝试不同的 k 值SELECTid,1.0/(60rank)ASrrf_k60,1.0/(100rank)ASrrf_k100FROMresults;8.2 性能瓶颈定位症状混合查询延迟明显高于单路查询。排查使用 EXPLAIN 查看执行计划确认是否触发了不必要的 CROSS JOIN检查数据倾斜问题EXPLAINANALYZESELECT*FROMproducts pWHEREMATCH_ANY(name,耳机)ANDl2_distance_approximate(embedding,:vec)0.5;九、总结与展望混合搜索是 Doris 4.0 在检索领域的核心创新。它通过 HSAP 架构实现了文本检索、向量检索和结构化查询的统一管理让用户用一条 SQL 就能完成复杂的多维检索需求。RRF 和 CC 融合算法为不同场景提供了灵活的排序策略。RRF 更适合对分数尺度不敏感、需要高鲁棒性的场景CC 更适合需要精确控制各通路权重的精细化运营场景。DataMind 的实践证明了这一架构在超大规模场景下的可行性。Tablet-level 的全局统计信息聚合、LTR 重排序模型的集成——这些高级特性为未来的 Doris 社区版本提供了宝贵的参考。展望未来我期待看到更多融合算法如 Learning to Rank 端到端训练、多模态检索文本图片音频的原生支持以及更智能的查询优化器自动选择最优融合策略。