news 2026/8/3 5:47:30

JAVA:Milvus 知识库如何对多个字段进行检索

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
JAVA:Milvus 知识库如何对多个字段进行检索

依赖:

milvus-sdk-java 2.4.x / 2.5.x(Milvus 2.x 服务端通用)
Maven

<dependency><groupId>io.milvus</groupId><artifactId>milvus-sdk-java</artifactId><version>2.5.0</version></dependency>

场景说明:

  1. 向量字段:embedding做语义相似度检索
  2. 多个标量字段通过expr过滤(category、source、create_time)
  3. Java SDK Search API 核心:searchParam.withExpr("多字段条件表达式")

集合Schema(对应代码示例)

字段类型说明
idINT64(主键)文档ID
embeddingFLOAT_VECTOR向量,dim=1024
categoryVARCHAR文档分类
sourceVARCHAR来源
create_timeINT64创建时间戳
contentVARCHAR文档正文

完整Java示例代码

importio.milvus.client.MilvusServiceClient;importio.milvus.common.clientenum.ConsistencyLevelEnum;importio.milvus.param.ConnectParam;importio.milvus.param.R;importio.milvus.param.dml.SearchParam;importio.milvus.response.SearchResultsWrapper;importio.milvus.grpc.DataType;importjava.util.ArrayList;importjava.util.List;publicclassMilvusMultiFieldSearchDemo{publicstaticvoidmain(String[]args){// 1. 创建Milvus客户端ConnectParamconnectParam=ConnectParam.newBuilder().withHost("127.0.0.1").withPort(19530)// 开启鉴权时添加// .withUsername("root")// .withPassword("xxxx").build();MilvusServiceClientclient=newMilvusServiceClient(connectParam);StringcollectionName="knowledge_base";// 2. 组装查询向量(业务中替换为文本向量化后的float数组)List<Float>queryVector=newArrayList<>();for(inti=0;i<1024;i++){queryVector.add(0.01f);}List<List<Float>>vectors=newArrayList<>();vectors.add(queryVector);// ======================// 【重点】多标量字段过滤表达式 expr// 语法规则:字符串使用双引号,and / or 组合多个条件// ======================Stringexpr="category == \"电力文档\" "+"and source in [\"内部手册\", \"规范文件\"] "+"and create_time > 1700000000";// 3. 构建Search参数SearchParamsearchParam=SearchParam.newBuilder().withCollectionName(collectionName).withVectors(vectors).withVectorFieldName("embedding")// 向量字段.withTopK(10)// 返回top10.withExpr(expr)// 多字段过滤条件.addOutField("id").addOutField("category").addOutField("source").addOutField("create_time").addOutField("content").withMetricType("COSINE").withParams("{\"nprobe\":16}").withConsistencyLevel(ConsistencyLevelEnum.EVENTUALLY).build();// 4. 执行检索R<SearchResultsWrapper>response=client.search(searchParam);if(!response.isSuccess()){System.err.println("检索失败: "+response.getException().getMessage());client.close();return;}SearchResultsWrapperresultsWrapper=response.getData();// 5. 解析结果List<SearchResultsWrapper.IDScore>hitList=resultsWrapper.getIDScore(0);for(SearchResultsWrapper.IDScorehit:hitList){longdocId=hit.getLongID();floatscore=hit.getScore();// 获取标量字段Stringcategory=resultsWrapper.getFieldData("category",0).getAsString(hit.getIndex());Stringsource=resultsWrapper.getFieldData("source",0).getAsString(hit.getIndex());Stringcontent=resultsWrapper.getFieldData("content",0).getAsString(hit.getIndex());LongcreateTime=resultsWrapper.getFieldData("create_time",0).getAsLong(hit.getIndex());System.out.printf("score=%.4f, id=%d%n",score,docId);System.out.printf("category=%s, source=%s, time=%d%n",category,source,createTime);System.out.println("content:"+content);System.out.println("------------------------");}client.close();}}

常用expr条件示例(直接复制修改)

// 示例1:and 多条件Stringexpr1="category == \"防洪\" and create_time > 1700000000";// 示例2:or 或条件Stringexpr2="source == \"内部手册\" or source == \"行业标准\"";// 示例3:模糊匹配 Milvus >=2.4 支持 likeStringexpr3="category == \"业扩报装\" and content like \"%营商环境%\"";// 示例4:not 取反Stringexpr4="category == \"应急管理\" and not source == \"草稿\"";

重要知识点(Java开发常见问题)

1. 多个向量字段如何检索?

Milvus不支持一次search同时检索多个向量列(无法同时指定多个vectorFieldName
解决方案:

  1. 分别执行两次search(标题向量、正文向量)
  2. 在Java代码内实现RRF倒数融合 / 加权分数融合合并结果

伪代码参考:

// 检索标题向量SearchParamparamTitle=buildSearch("title_emb",queryTitleVec,expr);// 检索正文向量SearchParamparamContent=buildSearch("embedding",queryContentVec,expr);// 拿到两组结果,自定义融合排序

2. 只想查询标量字段(不做向量检索)→ 使用QueryParam

importio.milvus.param.dml.QueryParam;QueryParamqueryParam=QueryParam.newBuilder().withCollectionName("knowledge_base").withExpr("category == \"电力文档\" and create_time > 1700000000").addOutField("id").addOutField("content").build();R<SearchResultsWrapper>queryResp=client.query(queryParam);

3. 性能优化建议

  1. 经常过滤的标量字段建立标量索引
// Java创建标量索引示例(VARCHAR/INT字段)IndexParamindexParam=IndexParam.newBuilder().withCollectionName(collectionName).withFieldName("category").withIndexType("TREE").build();client.createIndex(indexParam);
  1. 查询时使用ConsistencyLevelEnum.EVENTUALLY提升查询速度
  2. 不要写过于复杂的like模糊查询,海量数据很慢

4. 避坑清单

  1. expr 字符串必须双引号"文本",不要单引号
  2. expr不要直接拼接用户输入 →SQL注入风险!一定要参数化处理

生产建议:封装工具类,使用值替换,禁止字符串直接拼接用户原始文本

  1. 集合没有执行load()直接查询会报错
  2. 向量维度和建表dim不一致抛出异常
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/8/3 5:46:17

SpringBoot技术交流平台开发实战与架构解析

1. 项目概述&#xff1a;基于SpringBoot的IT技术交流平台设计与实现这个毕业设计项目是一个典型的Java Web应用开发案例&#xff0c;采用当前主流的SpringBoot框架构建IT技术交流和分享平台。作为计算机专业毕业设计的选题&#xff0c;它涵盖了从技术选型到部署上线的完整开发生…

作者头像 李华
网站建设 2026/8/3 5:42:17

AI 人工智能编程

AI人工智能编程是指利用人工智能技术和工具来辅助或自动化软件开发过程的实践&#xff0c;核心是通过自然语言与 AI 交互&#xff0c;让开发者从代码生产者转向架构设计者和监督者 。当前 AI 编程已进入‌‌Loop工程新阶段‌&#xff0c;AI Agent 可自主执行"触发→工作→…

作者头像 李华
网站建设 2026/8/3 5:41:34

魔术公式轮胎模型原理与Simulink实现详解

1. 轮胎动力学模型概述轮胎作为车辆与地面接触的唯一部件&#xff0c;其动力学特性直接影响着整车的操纵稳定性、制动性能和乘坐舒适性。在车辆动力学仿真中&#xff0c;准确建立轮胎模型是进行各类分析的基础前提。魔术公式&#xff08;Magic Formula&#xff09;轮胎模型因其…

作者头像 李华
网站建设 2026/8/3 5:41:29

三线表制作全攻略:Word、LaTeX、Python实战指南

这次我们来看一个非常实用的技能&#xff1a;三线表制作。在学术写作、技术报告、数据分析文档中&#xff0c;三线表因其简洁、专业、清晰的特性&#xff0c;成为展示数据的首选格式。很多人觉得用Word或LaTeX制作三线表很麻烦&#xff0c;其实掌握核心方法后&#xff0c;只需几…

作者头像 李华
网站建设 2026/8/3 5:41:13

构建可靠部署体系:从Docker、Kubernetes到CI/CD的工程实践

1. 项目概述&#xff1a;从“部署”说起&#xff0c;一个被低估的工程环节“部署”这个词&#xff0c;听起来平平无奇&#xff0c;甚至有点枯燥。在很多人的印象里&#xff0c;它可能就是一行命令&#xff0c;或者点击一下发布按钮。但作为一个在软件开发和运维一线摸爬滚打了十…

作者头像 李华
网站建设 2026/8/3 5:40:34

MyBatis二级缓存原理与实战优化指南

1. MyBatis二级缓存深度解析作为Java持久层框架的核心组件&#xff0c;MyBatis的二级缓存机制在实际开发中既能显著提升性能&#xff0c;又可能成为隐蔽问题的源头。我在电商系统高并发场景下曾因不当配置导致缓存穿透&#xff0c;最终通过源码分析找到解决方案。本文将结合实战…

作者头像 李华