Milvus混合检索返回空结果问题排查
避坑混合检索
目录
前言
最近公司的项目有一个milvus混合检索的功能设计,在添加过滤条件,检索目标向量时,返回的结果为空,即没有检索到任何数据,但是从Attu客户端检查,满足过滤条件是有entity的,这篇博客主要复盘这次典型的混合查询失败的问题原因,希望通过这次分享,帮助大家更深入地理解Milvus的检索机制,避免踩坑。
问题排查
-
下面这段程序是一个经典的milvus的混合检索java程序,只检索出满足过滤条件的向量实体
String filterExpr = String.format("manufacturer in ['%s']", placeholders); SearchReq searchReq = SearchReq.builder() .databaseName(CommonConstant.MATERIAL_MILVUS_DATABASE) .collectionName(CommonConstant.MATERIAL_NAME_MATCH_COLLECTION) .data(Collections.singletonList(floatVec)) .topK(CommonConstant.MILVUS_RETURN_NUM) .filter(filterExpr) //设置过滤条件 .outputFields(returnFields) .searchParams(searchParamsMap) .build(); -
但是这段程序在检索数据时,大多数数据是可以正确检索到,有些数据检索不到,且检索失败的数据,通过Attu客户端是可以看到满足过滤条件的,是有entity存在的。
-
因此我的初步排查方向包括:
数据是否存在:确认数据已成功插入并建立了索引。
过滤条件是否正确:检查过滤表达式语法无误,且集合中确实存在满足该标量条件的实体。
连接与集合状态:确认连接正常,集合已正确加载(load())。 -
进一步,还有一个可能,milvus只会检索出相似度大于某个阈值的数据,但是程序中并没有指定相似度阈值,查看官网信息,也没有看到有默认阈值的设定,因此,相似度阈值的原因也被排除掉。
-
那既然都没有问题,我就在Attu上测试,看看是不是milvus java sdk本身存在漏洞,因此打开attu客户端,在向量检索界面,设置查询失败的过滤条件,随机生成一个embedding进行测试,如图所示,依然查询失败。

-
但是在数据栏,直接进行标量检索时,是可以检索到数据的,说明是有entity满足过滤条件的,并不是没有数据导致的检索结果为空。

-
在以上方面均未发现异常后,我开始思考milvus向量检索本身,特别是索引和搜索参数的配置上。当时,为集合的向量字段建立的索引类型为IVF_FLAT,参数为 nlist=512。而在执行搜索时,设置的搜索参数是 nprobe=128,会不会是因为满足过滤条件的所有entity的embedding都是与检索向量相似度过低,并不在最相近的这128个“桶”内,因此,重新设置nprobe参数值,发现是可以检索出数据的,破案。

-
原因是我第一次使用milvus进行混合检索,疏忽了IVF_FLAT索引类型和过滤条件的 混合检索执行流程,导致刚发现问题时有点蒙。
IVF_FLAT索引检索过程
要理解为何这样设置会导致空结果,我们需要先了解IVF_FLAT索引的大致工作流程
- 索引构建(聚类):在构建索引时,Milvus会使用K-Means等算法将集合中的所有向量划分到nlist个聚类中心(桶)中。nlist=512意味着整个向量空间被划分成了512个簇。
- 搜索过程:当进行搜索时,对于一个给定的查询向量:
第一步:粗选桶。系统会计算该查询向量与所有512个聚类中心的距离,并选出距离最近的nprobe个桶。nprobe=128意味着系统只关注与查询向量最相似的128个桶。
第二步:桶内精搜。系统会在这128个桶内部进行精确的最近邻搜索(比如计算欧氏距离或余弦相似度),并按照相似度排序返回结果 - 关键点在于:混合查询中的标量过滤(条件过滤)发生在第二步之后,即先进行向量相似性搜索,再对得到的候选向量进行标量条件过滤,因此,如果符合条件过滤的embedding不在候选相似度排序的范围中,最后就会导致查询不到数据。
总结
本次对Milvus混合查询返回空结果的排查,揭示了深入理解索引和查询参数的重要性。IVF_FLAT索引中的nprobe参数直接控制了搜索的范围,在混合查询场景下,不合理的nprobe设置可能会使满足属性条件的数据因落在搜索范围外而被遗漏。
火山引擎开发者社区是火山引擎打造的AI技术生态平台,聚焦Agent与大模型开发,提供豆包系列模型(图像/视频/视觉)、智能分析与会话工具,并配套评测集、动手实验室及行业案例库。社区通过技术沙龙、挑战赛等活动促进开发者成长,新用户可领50万Tokens权益,助力构建智能应用。
更多推荐
所有评论(0)