ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

JAVA25+Spring Boot 4.1.0 +Spring AI 2.0.1 向量数据库milvus 基础功能实现

JAVA25+Spring Boot 4.1.0 +Spring AI 2.0.1 向量数据库milvus 基础功能实现

前置文章:
JAVA25 + Spring Boot 4.1.0 + Spring AI 2.0.1 调用 DeepSeek 模型
JAVA25 + Spring Boot 4.1.0 + Spring AI 2.0.1 加载本地 embeddings 模型 bge-m3

前言

向量数据库是一种特殊类型的数据库,在人工智能应用中扮演着至关重要的角色。

向量数据库的查询方式与传统关系型数据库有所不同:它不进行精确匹配,而是执行相似性搜索。当以向量作为查询条件时,向量数据库会返回与查询向量“相似”的向量。关于相似度的具体计算方式,请参阅“向量相似性”一节。

向量数据库用于将数据与人工智能模型集成。使用向量数据库的第一步,是把数据加载到向量数据库中;随后,当用户向人工智能模型发起查询时,系统会先检索出一组相似的文档,这些文档将作为用户问题的上下文,与用户的查询一并发送给人工智能模型。这种技术被称为检索增强生成(RAG)。

Spring AI 提供了大量接口,支持多种向量数据库实现,并附有若干进阶用法示例。详细信息可查阅官方文档:
Spring AI 官网 Vector Databases
Spring AI 官网 Vector Databases Milvus

本文在前置文章的基础上进一步扩展,讲解如何在项目中使用 Spring AI 对接 Milvus 向量数据库。

注意:请务必先完成前置文章JAVA25 + Spring Boot 4.1.0 + Spring AI 2.0.1 加载本地 embeddings 模型 bge-m3中的配置,否则项目启动时会报错。

一、安装 Milvus 3.0.x:

Milvus 3.0.x 版本里面会更新了很多功能,为了以后扩展建议安装 Milvus 3.0.x。
Milvus 官网
Milvus 官网安装页面

  • 安装 Milvus
wgethttps://github.com/milvus-io/milvus/releases/download/v3.0.3/milvus-standalone-docker-compose.yaml-Odocker-compose.yamlsudodockercompose up-dCreating milvus-etcd...doneCreating milvus-minio...doneCreating milvus-standalone...done

注意:指令在哪个文件夹下运行会在当前目录创建数据文件,创建的数据文件记得给权限,否则docker 启动有可能报错。

  • 停止并删除 Milvus
sudodockercompose downsudorm-rfvolumes
  • 安装 Milvus 连接工具
    Attu 首页
    下载 Attu 页面

二、Maven 引入

<!-- Milvus 向量存储 (Spring AI 官方 Starter) --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-vector-store-milvus</artifactId></dependency>

三、添加 application.yml 配置

# Spring 配置spring:# ==================== Spring AI 配置 ====================ai:# ==================== 向量库配置 ====================vectorstore:# ==================== Milvus 向量库配置 ====================milvus:client:# 连接 Milvus 向量库 IPhost:"121.43.122.232"# 连接 Milvus 向量库端口port:19530# username: "root"# password: "Milvus"#默认数据库名称databaseName:"default"#数据库中集合名称collectionName:"vector_store"#存入 Milvus 的向量(Embedding)的维度大小 务必与 向量化模型 输出维度一致embeddingDimension:1024# 索引类型 IVF_FLAT(适合中等规模数据,平衡查询速度和精度)indexType:IVF_FLAT# 相似度度量类型 ( COSINE 余弦相似度,常用于文本向量)metricType:COSINE#是否要为你自动在 Milvus 中创建用于存储向量数据的集合(Collection)及其结构(Schema)initializeSchema:true

四、创建 DTO

  • 向量新增修改请求参数记录对象
importio.swagger.v3.oas.annotations.media.Schema;importlombok.*;importlombok.experimental.Accessors;importorg.springframework.ai.document.Document;importjava.io.Serial;importjava.io.Serializable;importjava.util.List;/** * @description: 向量新增修改请求参数记录对象 * @author: LIHAO * @createDate: 2026-11-02 17:13:49 */@Data@Builder(toBuilder=true)@With@NoArgsConstructor@AllArgsConstructor@Accessors(chain=true)@Schema(title="向量新增修改请求参数对象")publicclassVectorUpsertRequestimplementsSerializable{@SerialprivatestaticfinallongserialVersionUID=1L;@Schema(description="存储名称,用于标识使用的向量存储实例(RedisVectorStore Bean名称)(主要作用获取集合名称,如果传递collectionName参数以collectionName参数为主。没有传递以storeBeanName获取为主)")privateStringstoreBeanName;@Schema(description="集合名称")privateStringcollectionName;@Schema(description="分区名称,一个数据库中一个集合里面的不同分区名称")privateStringpartitionName;@Schema(description="拆分好的文档数据",requiredMode=Schema.RequiredMode.REQUIRED)privateList<Document>documentList;}
  • 向量检索请求参数
importio.swagger.v3.oas.annotations.media.Schema;importlombok.*;importlombok.experimental.Accessors;importjava.io.Serial;importjava.io.Serializable;importjava.util.List;/** * @description: 向量检索请求参数 * @author: LIHAO * @createDate: 2026-11-02 17:13:58 */@Data@Builder(toBuilder=true)@With@NoArgsConstructor@AllArgsConstructor@Accessors(chain=true)@Schema(title="向量检索请求参数对象")publicclassVectorQueryRequestimplementsSerializable{@SerialprivatestaticfinallongserialVersionUID=1L;@Schema(description="向量数据id")privateStringid;@Schema(description="向量数据id集合")privateList<String>idList;@Schema(description="存储Bean名称,用于标识使用的向量存储实例(RedisVectorStore Bean名称)(主要作用获取集合名称,如果传递collectionName参数以collectionName参数为主。没有传递以storeBeanName获取为主)")privateStringstoreBeanName;@Schema(description="集合名称")privateStringcollectionName;@Schema(description="分区名称,一个数据库中一个集合里面有不同分区名称")privateStringpartitionName;@Schema(description="检索文本",requiredMode=Schema.RequiredMode.AUTO)privateStringtext;@Schema(description="返回结果数量,可为空(使用系统默认值,通常为4)")privateIntegertopK;@Schema(description="相似度阈值,仅返回相似度高于此值的文档,范围通常为0~1,可为空(系统默认值,通常为0.0无阈值限制)")privateFloatsimilarityThreshold;@Schema(description="是否重排序,true:重排序,false不重排序")privateBooleanisReranker;@Schema(description="元数据过滤条件,用于在检索时对文档元数据进行过滤,"+"如果添加向量时是章节拆分,默认添加元数据字段fileName(文件名称)、chapters(章)、section(节)、subsection(小节)、detailedChapters(章/节/小节)"+"语法示例:(metadata['country'] == 'UK' && metadata['year'] >= 2020 && metadata['isActive'] == true Or metadata['country'] == 'BG' && (metadata['city'] NOT IN ['Sofia', 'Plovdiv'] || price < 134.34))")privateStringmetaDataWhere;@Schema(description="分词匹配词间隔位置,允许匹配词之间最多间隔几个位置,0代表必须相邻,中间没有间隔位置。(只限于短语匹配)")privateIntegerslop;}

五、创建向量库操作 Service

importcom.lh.vectorDatabases.milvus.dto.VectorQueryRequest;importcom.lh.vectorDatabases.milvus.dto.VectorUpsertRequest;importlombok.extern.slf4j.Slf4j;importorg.apache.commons.collections4.CollectionUtils;importorg.apache.commons.lang3.StringUtils;importorg.springframework.ai.document.Document;importorg.springframework.ai.vectorstore.SearchRequest;importorg.springframework.ai.vectorstore.VectorStore;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.stereotype.Service;importorg.springframework.util.Assert;importjava.util.List;importjava.util.Map;/** * @description: Milvus Store 向量操作 * @author: LIHAO * @createDate: 2026-11-02 15:05:58 */@Slf4j@Service("milvusVectorStoreService")publicclassMilvusVectorStoreService{privateVectorStorevectorStore;publicMilvusVectorStoreService(VectorStorevectorStore){this.vectorStore=vectorStore;}/** * @description: 新增或修改向量数据 * @author: LIHAO * @createDate: 2026-11-02 17:16:58 * @param: [storeBeanName RedisVectorStore Bean名称, documentList] * @return: void */publicvoidupsert(VectorUpsertRequestvectorAddRequest){List<Document>documentParamtList=vectorAddRequest.getDocumentList();// 检查集合不为空Assert.notEmpty(documentParamtList,"MilvusVectorStoreService#upsert,参数vectorRequest#documentList不能为空!");//新增或修改数据vectorStore.add(documentParamtList);}/** * @description: 根据数据id据删除数据 * @author: LIHAO * @createDate: 2026-11-02 17:16:58 * @param: [storeBeanName RedisVectorStore Bean名称, idList 数据id] * @return: void */publicvoiddeleteById(VectorQueryRequestvectorRequest){List<String>idList=vectorRequest.getIdList();// 检查集合不为空Assert.notEmpty(idList,"MilvusVectorStoreService#deleteById,参数vectorRequest#idList不能为空!");if(CollectionUtils.isNotEmpty(idList)){//删除数据vectorStore.delete(idList);}}/** * @description: 根据文本查询相关向量数据(如语义搜索) * @author: LIHAO * @createDate: 2026-11-02 17:16:58 * @param: [vectorRequest] * @return: java.util.List<org.springframework.ai.document.Document> */publicList<Document>searchByVector(VectorQueryRequestvectorRequest){//搜索内容Stringtext=vectorRequest.getText();//检查字符串不为空(不是 null,且长度 > 0)Assert.hasLength(text,"MilvusVectorStoreService#searchByVector,参数vectorRequest#text不能为空!");// 构建 SearchRequest,先设置固定参数SearchRequest.Builderbuilder=SearchRequest.builder().query(vectorRequest.getText());// 查询文本//获取搜索结果数量IntegertopK=vectorRequest.getTopK();// 仅当 topK 不为 null 时才设置 topK,否则使用系统默认值4(由 RedisVectorStore 决定)if(topK!=null&&topK>0){builder.topK(topK);}//获取相似度阈值,仅返回相似度高于此值的文档,范围通常为0~1,可为空(系统默认值,通常为0.0无阈值限制)FloatsimilarityThreshold=vectorRequest.getSimilarityThreshold();// similarityThreshold 不为 null 时才设置 similarityThreshold,否则使用系统默认值0.0(由 RedisVectorStore 决定)if(similarityThreshold!=null&&similarityThreshold>=0.0&&similarityThreshold<=1.0){builder.similarityThreshold(similarityThreshold);// 相似度阈值(若为 null,builder 可能使用默认值)}//元数据过滤条件,用于在检索时对文档元数据进行过滤StringmetaDataWhere=vectorRequest.getMetaDataWhere();// 判断是否有元数据过滤if(StringUtils.isNotBlank(metaDataWhere)){builder.filterExpression(metaDataWhere);// 元数据过滤条件 metaDataWhere}// 生成最终的 SearchRequest 对象SearchRequestsearchRequest=builder.build();//查询向量数据List<Document>results=vectorStore.similaritySearch(searchRequest);returnresults;}}

六、测试用例

  • Maven 引入:
<!-- Milvus 向量存储 (Spring AI 官方 Starter) --><dependency><groupId>org.springframework.ai</groupId><artifactId>spring-ai-starter-vector-store-milvus</artifactId></dependency>
  • java代码
importcom.lh.vectorDatabases.milvus.dto.VectorQueryRequest;importcom.lh.vectorDatabases.milvus.dto.VectorUpsertRequest;importcom.lh.vectorDatabases.milvus.service.MilvusVectorStoreService;importlombok.extern.slf4j.Slf4j;importorg.apache.commons.collections4.CollectionUtils;importorg.junit.jupiter.api.Test;importorg.springframework.ai.document.Document;importorg.springframework.beans.factory.annotation.Autowired;importorg.springframework.boot.test.context.SpringBootTest;importjava.util.List;importjava.util.Map;@Slf4j@SpringBootTestpublicclassOriginApplicationTest{@AutowiredprivateMilvusVectorStoreServicemilvusVectorStoreService;@TestpublicvoidmilvusVectorStoreTest(){List<Document>documents=List.of(newDocument("今天天气很好",Map.of("meta1","meta1")),newDocument("世界很大,救赎就在拐角处"),newDocument("你面对过去向前走,然后转身面向未来。",Map.of("meta2","meta2")));//新增数据milvusVectorStoreService.upsert(VectorUpsertRequest.builder().documentList(documents).build());//查询数据List<Document>results=milvusVectorStoreService.searchByVector(VectorQueryRequest.builder().text("今天").topK(20).build());System.out.println(results);if(CollectionUtils.isNotEmpty(results)){List<String>idList=results.stream().map(Document::getId).toList();//根据id删除数据milvusVectorStoreService.deleteById(VectorQueryRequest.builder().idList(idList).build());}}}

七、总结

本文围绕 Spring AI 对接 Milvus 向量数据库,完整走通了从环境搭建到代码落地的全流程,主要包含以下几个环节:

  • 环境准备:通过 Docker Compose 安装 Milvus 3.0.x,并使用 Attu 作为可视化管理工具,方便查看集合与向量数据。
  • 依赖与配置:引入spring-ai-starter-vector-store-milvus官方 Starter,在application.yml中完成连接地址、集合名称、向量维度、索引类型与相似度度量等关键参数配置。
  • 请求对象封装:通过VectorUpsertRequest与VectorQueryRequest统一承载新增、删除、检索所需的参数,便于后续扩展与复用。
  • 服务层实现:MilvusVectorStoreService基于 Spring AI 的VectorStore抽象,实现了向量新增/修改、按 ID 删除以及基于文本的相似性检索,并对入参做了必要的校验。
  • 测试验证:通过单元测试完成「写入 → 检索 → 删除」的闭环验证,确认配置与代码均可正常工作。

需要特别注意的几点:

  1. embeddingDimension必须与所用向量化模型(如 bge-m3)的输出维度保持一致,否则写入时会报维度不匹配错误。
  2. initializeSchema: true可让 Spring AI 自动创建集合与 Schema,生产环境建议改为手动管理,避免误建或结构变更。
  3. 检索时topK、similarityThreshold等参数可按业务场景灵活调整,配合metaDataWhere元数据过滤能显著提升召回质量。

至此,Spring AI + Milvus 的基础集成已经完成。后续可以在此基础上继续扩展:接入 RAG 问答链路、结合重排序模型优化召回结果,或将向量检索能力封装为统一的内部服务,供多个业务模块调用。

RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进