embeddingModel操作milvus数据库集合
2026/9/24 15:11:55 网站建设 项目流程

案例:

不是"创建集合的那一瞬间",而是"第一次使用时"

// ========== 应用启动时(MilvusConfig执行) ==========// 步骤1: 创建milvusClient@BeanpublicMilvusServiceClientmilvusClient(){returnnewMilvusServiceClient(...);// ✓ 只是连接数据库}// 步骤2: 创建embeddingModel@BeanpublicEmbeddingModelembeddingModel(){returnnewOpenAiEmbeddingModel(...);// ✓ 只是创建工具对象}// 步骤3: 创建vectorStore@BeanpublicVectorStorezyVectorStore(MilvusServiceClientmilvusClient,EmbeddingModelembeddingModel){MilvusVectorStorevectorStore=MilvusVectorStore.builder(milvusClient,embeddingModel).collectionName("zhi_yan").initializeSchema(true)// ← 注意!这里只是设置参数.build();// ⚠️ 到这里为止,集合还没有创建!// 只是创建了vectorStore对象,保存了配置returnvectorStore;}// ========== 启动完成,集合仍然不存在 ==========

集合真正创建的时机

第一次调用vectorStore.add()

// ========== 用户上传文件后 ==========DocumentServiceImpl.importMarkdownContent(){// 1. 切片List<Document>chunks=textSplitter.apply(List.of(doc));// 2. 调用vectorStore.add() ← 这里才真正创建集合!vectorStore.add(chunks);}// ========== vectorStore.add()内部执行流程 ==========classMilvusVectorStore{publicvoidadd(List<Document>documents){// 步骤1: 检查集合是否存在booleanexists=checkCollectionExists("zhi_yan");if(!exists&&initializeSchema){// 步骤2: 集合不存在,需要创建createCollection();// ← 这里才真正创建!}// 步骤3: 插入数据insertDocuments(documents);}privatevoidcreateCollection(){// ========== 这里才使用embeddingModel! ==========// 1. 生成一个测试向量,获取维度log.info("正在获取向量维度...");List<Double>testVector=embeddingModel.embed("test");intdimension=testVector.size();// ← 得到1024log.info("检测到向量维度: {}",dimension);// 2. 创建SchemaList<FieldType>fields=newArrayList<>();// 主键字段fields.add(FieldType.newBuilder().withName("id").withDataType(DataType.VarChar).withMaxLength(36).withPrimaryKey(true).build());// 向量字段 ← 使用检测到的维度fields.add(FieldType.newBuilder().withName("embedding").withDataType(DataType.FloatVector).withDimension(dimension)// ← 1024.build());// 其他字段...// 3. 创建集合CollectionSchemaParamschema=CollectionSchemaParam.newBuilder().withFieldTypes(fields).build();CreateCollectionParamparam=CreateCollectionParam.newBuilder().withCollectionName("zhi_yan").withSchema(schema).build();milvusClient.createCollection(param);log.info("集合创建成功! embedding字段维度: {}",dimension);}}

完整时间线

时间点1: 应用启动 ├─ 创建milvusClient ✓ ├─ 创建embeddingModel ✓ (配置为1024维) ├─ 创建vectorStore ✓ (保存配置) └─ 集合状态: ❌ 不存在 时间点2: 应用启动完成 └─ 集合状态: ❌ 仍然不存在 时间点3: 用户上传第一个文件 ├─ DocumentController接收文件 ├─ DocumentServiceImpl.importMarkdownContent() ├─ textSplitter.apply() 切片 └─ vectorStore.add(chunks) ← 触发! ↓ 时间点4: vectorStore.add()内部 ├─ 检查集合是否存在 → 不存在 ├─ 调用embeddingModel.embed("test") → 得到1024维向量 ├─ 创建集合,embedding字段设为1024维 ✓ └─ 集合状态: ✓ 创建成功,1024维 时间点5: 后续上传文件 ├─ vectorStore.add(chunks) ├─ 检查集合是否存在 → 已存在 ├─ 跳过创建步骤 └─ 直接插入数据

验证:查看Spring AI源码逻辑

// Spring AI的MilvusVectorStore实际实现(简化版)publicclassMilvusVectorStoreimplementsVectorStore{privatefinalMilvusServiceClientmilvusClient;privatefinalEmbeddingModelembeddingModel;privatefinalStringcollectionName;privatefinalbooleaninitializeSchema;@Overridepublicvoidadd(List<Document>documents){// 1. 确保集合存在if(initializeSchema){createCollectionIfNotExists();// ← 关键方法}// 2. 向量化并插入for(Documentdoc:documents){List<Double>vector=embeddingModel.embed(doc.getContent());insert(doc.getId(),vector,doc.getContent(),doc.getMetadata());}}privatevoidcreateCollectionIfNotExists(){// 检查集合是否存在R<Boolean>response=milvusClient.hasCollection(HasCollectionParam.newBuilder().withCollectionName(collectionName).build());if(!response.getData()){// 集合不存在,创建它log.info("集合 {} 不存在,正在创建...",collectionName);// ========== 这里使用embeddingModel获取维度 ==========List<Double>dimensionVector=embeddingModel.embed("dimension test");intdimension=dimensionVector.size();log.info("从EmbeddingModel检测到向量维度: {}",dimension);// 创建Schema并创建集合createCollectionWithDimension(dimension);}else{log.info("集合 {} 已存在,跳过创建",collectionName);}}}

为什么这样设计?

1. 延迟初始化(Lazy Initialization)

好处: ✓ 启动更快 - 不需要在启动时创建集合 ✓ 灵活性 - 可以先启动应用,后配置Milvus ✓ 自动适配 - 自动从embeddingModel获取维度,不需要手动配置

2. 自动维度检测

// 你不需要这样写:MilvusVectorStore.builder(...).dimension(1024)// ❌ 不需要手动指定.build();// 而是自动检测:MilvusVectorStore.builder(...).initializeSchema(true)// ✓ 自动从embeddingModel获取.build();// 内部会:intdimension=embeddingModel.embed("test").size();// 自动得到1024

实际操作演示

场景1: 首次启动,集合不存在

# 1. 启动应用mvn spring-boot:run# 控制台输出:# [INFO] 正在连接Milvus服务器: 10.0.0.15:19530# [INFO] Milvus客户端连接成功# [INFO] 正在创建OpenAI EmbeddingModel...# [INFO] OpenAI EmbeddingModel创建成功# [INFO] 正在创建Milvus VectorStore,集合名称: zhi_yan# [INFO] Milvus VectorStore创建成功# [INFO] 应用启动完成!# ⚠️ 注意:这里没有"创建集合"的日志!# 2. 上传第一个文件curl-XPOST http://localhost:8084/api/documents/import\-F"file=@test.md"# 控制台输出:# [INFO] 正在导入Markdown文件: test.md# [INFO] 开始导入Markdown内容,文件名: test.md# [INFO] 文档已分割成 3 个块# [INFO] 集合 zhi_yan 不存在,正在创建... ← 这里才创建!# [INFO] 正在获取向量维度...# [INFO] 从EmbeddingModel检测到向量维度: 1024# [INFO] 创建集合Schema: embedding字段维度=1024# [INFO] 集合创建成功!# [INFO] 成功导入 3 个文档块到Milvus

场景2: 集合已存在

# 上传第二个文件curl-XPOST http://localhost:8084/api/documents/import\-F"file=@test2.md"# 控制台输出:# [INFO] 正在导入Markdown文件: test2.md# [INFO] 开始导入Markdown内容,文件名: test2.md# [INFO] 文档已分割成 4 个块# [INFO] 集合 zhi_yan 已存在,跳过创建 ← 跳过创建步骤# [INFO] 成功导入 4 个文档块到Milvus

总结

集合什么时候创建?

不是启动时,而是第一次调用vectorStore.add()时!

embeddingModel什么时候参与?

启动时: 只是创建embeddingModel对象,不调用 ↓ 第一次add()时: ├─ 调用embeddingModel.embed("test") ├─ 获取向量维度(1024) └─ 创建集合,设置embedding字段为1024维

为什么是1024?

因为你配置了: .dimensions(1024) ↓ embeddingModel.embed("test") 返回1024维向量 ↓ vectorStore检测到1024维 ↓ 创建集合时设置embedding字段为1024维

关键代码

// initializeSchema(true) 的作用:// 在第一次add()时,自动创建集合,并从embeddingModel获取维度MilvusVectorStore.builder(...).initializeSchema(true)// ← 这个参数很关键!.build();

集合是在第一次使用时才创建的,不是启动时! 🎯

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询