多彩编程 多彩编程MZPH · CODE BLOG
ARTICLE DETAIL

文章详情

深耕前端与后端开发技术的一线实战笔记与踩坑复盘。

embeddingModel操作milvus数据库集合

embeddingModel操作milvus数据库集合 案例不是创建集合的那一瞬间,而是第一次使用时// 应用启动时(MilvusConfig执行) // 步骤1: 创建milvusClientBeanpublicMilvusServiceClientmilvusClient(){returnnewMilvusServiceClient(...);// ✓ 只是连接数据库}// 步骤2: 创建embeddingModelBeanpublicEmbeddingModelembeddingModel(){returnnewOpenAiEmbeddingModel(...);// ✓ 只是创建工具对象}// 步骤3: 创建vectorStoreBeanpublicVectorStorezyVectorStore(MilvusServiceClientmilvusClient,EmbeddingModelembeddingModel){MilvusVectorStorevectorStoreMilvusVectorStore.builder(milvusClient,embeddingModel).collectionName(zhi_yan).initializeSchema(true)// ← 注意!这里只是设置参数.build();// ⚠️ 到这里为止,集合还没有创建!// 只是创建了vectorStore对象,保存了配置returnvectorStore;}// 启动完成,集合仍然不存在 集合真正创建的时机第一次调用vectorStore.add()时// 用户上传文件后 DocumentServiceImpl.importMarkdownContent(){// 1. 切片ListDocumentchunkstextSplitter.apply(List.of(doc));// 2. 调用vectorStore.add() ← 这里才真正创建集合!vectorStore.add(chunks);}// vectorStore.add()内部执行流程 classMilvusVectorStore{publicvoidadd(ListDocumentdocuments){// 步骤1: 检查集合是否存在booleanexistscheckCollectionExists(zhi_yan);if(!existsinitializeSchema){// 步骤2: 集合不存在,需要创建createCollection();// ← 这里才真正创建!}// 步骤3: 插入数据insertDocuments(documents);}privatevoidcreateCollection(){// 这里才使用embeddingModel! // 1. 生成一个测试向量,获取维度log.info(正在获取向量维度...);ListDoubletestVectorembeddingModel.embed(test);intdimensiontestVector.size();// ← 得到1024log.info(检测到向量维度: {},dimension);// 2. 创建SchemaListFieldTypefieldsnewArrayList();// 主键字段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. 创建集合CollectionSchemaParamschemaCollectionSchemaParam.newBuilder().withFieldTypes(fields).build();CreateCollectionParamparamCreateCollectionParam.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(ListDocumentdocuments){// 1. 确保集合存在if(initializeSchema){createCollectionIfNotExists();// ← 关键方法}// 2. 向量化并插入for(Documentdoc:documents){ListDoublevectorembeddingModel.embed(doc.getContent());insert(doc.getId(),vector,doc.getContent(),doc.getMetadata());}}privatevoidcreateCollectionIfNotExists(){// 检查集合是否存在RBooleanresponsemilvusClient.hasCollection(HasCollectionParam.newBuilder().withCollectionName(collectionName).build());if(!response.getData()){// 集合不存在,创建它log.info(集合 {} 不存在,正在创建...,collectionName);// 这里使用embeddingModel获取维度 ListDoubledimensionVectorembeddingModel.embed(dimension test);intdimensiondimensionVector.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();// 内部会:intdimensionembeddingModel.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\-Ffiletest.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\-Ffiletest2.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();集合是在第一次使用时才创建的,不是启动时!
返回列表