
依赖milvus-sdk-java 2.4.x / 2.5.xMilvus 2.x 服务端通用MavendependencygroupIdio.milvus/groupIdartifactIdmilvus-sdk-java/artifactIdversion2.5.0/version/dependency场景说明向量字段embedding做语义相似度检索多个标量字段通过expr过滤category、source、create_timeJava SDK Search API 核心searchParam.withExpr(多字段条件表达式)集合Schema对应代码示例字段类型说明idINT64(主键)文档IDembeddingFLOAT_VECTOR向量dim1024categoryVARCHAR文档分类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客户端ConnectParamconnectParamConnectParam.newBuilder().withHost(127.0.0.1).withPort(19530)// 开启鉴权时添加// .withUsername(root)// .withPassword(xxxx).build();MilvusServiceClientclientnewMilvusServiceClient(connectParam);StringcollectionNameknowledge_base;// 2. 组装查询向量业务中替换为文本向量化后的float数组ListFloatqueryVectornewArrayList();for(inti0;i1024;i){queryVector.add(0.01f);}ListListFloatvectorsnewArrayList();vectors.add(queryVector);// // 【重点】多标量字段过滤表达式 expr// 语法规则字符串使用双引号and / or 组合多个条件// Stringexprcategory \电力文档\ and source in [\内部手册\, \规范文件\] and create_time 1700000000;// 3. 构建Search参数SearchParamsearchParamSearchParam.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. 执行检索RSearchResultsWrapperresponseclient.search(searchParam);if(!response.isSuccess()){System.err.println(检索失败: response.getException().getMessage());client.close();return;}SearchResultsWrapperresultsWrapperresponse.getData();// 5. 解析结果ListSearchResultsWrapper.IDScorehitListresultsWrapper.getIDScore(0);for(SearchResultsWrapper.IDScorehit:hitList){longdocIdhit.getLongID();floatscorehit.getScore();// 获取标量字段StringcategoryresultsWrapper.getFieldData(category,0).getAsString(hit.getIndex());StringsourceresultsWrapper.getFieldData(source,0).getAsString(hit.getIndex());StringcontentresultsWrapper.getFieldData(content,0).getAsString(hit.getIndex());LongcreateTimeresultsWrapper.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条件示例直接复制修改// 示例1and 多条件Stringexpr1category \防洪\ and create_time 1700000000;// 示例2or 或条件Stringexpr2source \内部手册\ or source \行业标准\;// 示例3模糊匹配 Milvus 2.4 支持 likeStringexpr3category \业扩报装\ and content like \%营商环境%\;// 示例4not 取反Stringexpr4category \应急管理\ and not source \草稿\;重要知识点Java开发常见问题1. 多个向量字段如何检索Milvus不支持一次search同时检索多个向量列无法同时指定多个vectorFieldName解决方案分别执行两次search标题向量、正文向量在Java代码内实现RRF倒数融合 / 加权分数融合合并结果伪代码参考// 检索标题向量SearchParamparamTitlebuildSearch(title_emb,queryTitleVec,expr);// 检索正文向量SearchParamparamContentbuildSearch(embedding,queryContentVec,expr);// 拿到两组结果自定义融合排序2. 只想查询标量字段不做向量检索→ 使用QueryParamimportio.milvus.param.dml.QueryParam;QueryParamqueryParamQueryParam.newBuilder().withCollectionName(knowledge_base).withExpr(category \电力文档\ and create_time 1700000000).addOutField(id).addOutField(content).build();RSearchResultsWrapperqueryRespclient.query(queryParam);3. 性能优化建议经常过滤的标量字段建立标量索引// Java创建标量索引示例VARCHAR/INT字段IndexParamindexParamIndexParam.newBuilder().withCollectionName(collectionName).withFieldName(category).withIndexType(TREE).build();client.createIndex(indexParam);查询时使用ConsistencyLevelEnum.EVENTUALLY提升查询速度不要写过于复杂的like模糊查询海量数据很慢4. 避坑清单expr 字符串必须双引号文本不要单引号expr不要直接拼接用户输入 →SQL注入风险一定要参数化处理生产建议封装工具类使用值替换禁止字符串直接拼接用户原始文本集合没有执行load()直接查询会报错向量维度和建表dim不一致抛出异常