diff --git a/MILVUS_IMPLEMENTATION_GUIDE.md b/MILVUS_IMPLEMENTATION_GUIDE.md new file mode 100644 index 00000000..181a52ec --- /dev/null +++ b/MILVUS_IMPLEMENTATION_GUIDE.md @@ -0,0 +1,237 @@ +# Milvus向量库实现指南 + +## 概述 + +本项目已完成Milvus向量库的集成,基于Milvus SDK 2.6.4版本实现。Milvus是一个开源的向量数据库,专为AI应用和相似性搜索而设计。 + +## 实现特性 + +### ✅ 已实现功能 + +1. **集合管理** + - 自动创建集合(Collection) + - 检查集合是否存在 + - 删除集合 + +2. **数据存储** + - 批量插入向量数据 + - 支持文本、fid、kid、docId等元数据 + - 自动生成向量嵌入 + +3. **向量搜索** + - 基于相似性的向量搜索 + - 支持TopK结果返回 + - 返回相关文本内容 + +4. **数据删除** + - 按文档ID删除 + - 按片段ID删除 + - 删除整个集合 + +## 架构设计 + +### 策略模式实现 + +``` +AbstractVectorStoreStrategy (抽象基类) + ↓ +MilvusVectorStoreStrategy (Milvus实现) +WeaviateVectorStoreStrategy (Weaviate实现) +``` + +### 核心类说明 + +- **MilvusVectorStoreStrategy**: Milvus向量库策略实现 +- **VectorStoreStrategyFactory**: 向量库策略工厂,支持动态切换 +- **VectorStoreService**: 向量库服务接口 + +## 配置说明 + +### 必需配置项 + +在系统配置中需要设置以下Milvus相关配置: + +```properties +# Milvus服务地址 +milvus.url=http://localhost:19530 + +# 集合名称前缀 +milvus.collectionname=LocalKnowledge + +# 向量库类型选择 +vector.store_type=milvus +``` + +### 集合Schema设计 + +每个集合包含以下字段: + +| 字段名 | 类型 | 说明 | +|--------|------|------| +| id | Int64 | 主键,自动生成 | +| text | VarChar(65535) | 文本内容 | +| fid | VarChar(255) | 片段ID | +| kid | VarChar(255) | 知识库ID | +| docId | VarChar(255) | 文档ID | +| vector | FloatVector(1024) | 向量数据 | + +### 索引配置 + +- **索引类型**: IVF_FLAT +- **距离度量**: L2 (欧几里得距离) +- **参数**: nlist=1024 + +## 使用示例 + +### 1. 创建集合 + +```java +MilvusVectorStoreStrategy strategy = new MilvusVectorStoreStrategy(configService); +strategy.createSchema("bge-large-zh-v1.5", "test001", "test-model"); +``` + +### 2. 存储向量数据 + +```java +StoreEmbeddingBo storeEmbeddingBo = new StoreEmbeddingBo(); +storeEmbeddingBo.setVectorModelName("bge-large-zh-v1.5"); +storeEmbeddingBo.setKid("test001"); +storeEmbeddingBo.setDocId("doc001"); +storeEmbeddingBo.setChunkList(Arrays.asList("文本1", "文本2")); +storeEmbeddingBo.setFids(Arrays.asList("fid001", "fid002")); + +strategy.storeEmbeddings(storeEmbeddingBo); +``` + +### 3. 查询向量数据 + +```java +QueryVectorBo queryVectorBo = new QueryVectorBo(); +queryVectorBo.setQuery("查询文本"); +queryVectorBo.setKid("test001"); +queryVectorBo.setMaxResults(5); + +List results = strategy.getQueryVector(queryVectorBo); +``` + +### 4. 删除数据 + +```java +// 按文档ID删除 +strategy.removeByDocId("doc001", "test001"); + +// 按片段ID删除 +strategy.removeByFid("fid001", "test001"); + +// 删除整个集合 +strategy.removeById("test001", "model"); +``` + +## 部署要求 + +### Milvus服务部署 + +1. **Docker部署** (推荐) +```bash +# 下载docker-compose文件 +wget https://github.com/milvus-io/milvus/releases/download/v2.6.4/milvus-standalone-docker-compose.yml -O docker-compose.yml + +# 启动Milvus +docker-compose up -d +``` + +2. **验证部署** +```bash +# 检查服务状态 +docker-compose ps + +# 查看日志 +docker-compose logs milvus-standalone +``` + +### 系统要求 + +- **内存**: 最少8GB,推荐16GB+ +- **存储**: SSD推荐,至少50GB可用空间 +- **CPU**: 4核心以上 +- **网络**: 确保19530端口可访问 + +## 性能优化 + +### 1. 索引优化 + +根据数据量调整索引参数: +- 小数据集(<100万): nlist=1024 +- 中等数据集(100万-1000万): nlist=4096 +- 大数据集(>1000万): nlist=16384 + +### 2. 批量操作 + +- 批量插入:建议每批1000-10000条记录 +- 批量查询:避免频繁的单条查询 + +### 3. 内存管理 + +```yaml +# docker-compose.yml中的内存配置 +environment: + MILVUS_CONFIG_PATH: /milvus/configs/milvus.yaml +volumes: + - ./milvus.yaml:/milvus/configs/milvus.yaml +``` + +## 故障排除 + +### 常见问题 + +1. **连接失败** + - 检查Milvus服务是否启动 + - 验证网络连接和端口 + - 确认配置中的URL正确 + +2. **集合创建失败** + - 检查集合名称是否符合规范 + - 验证字段定义是否正确 + - 查看Milvus日志获取详细错误 + +3. **插入数据失败** + - 确认向量维度与schema一致 + - 检查数据格式是否正确 + - 验证集合是否已加载 + +4. **查询无结果** + - 确认集合中有数据 + - 检查查询参数设置 + - 验证向量化模型一致性 + +### 日志调试 + +启用详细日志: +```properties +logging.level.org.ruoyi.service.strategy.impl.MilvusVectorStoreStrategy=DEBUG +logging.level.io.milvus=DEBUG +``` + +## 与Weaviate对比 + +| 特性 | Milvus | Weaviate | +|------|--------|----------| +| 性能 | 高性能,专为大规模设计 | 中等性能 | +| 部署 | 需要独立部署 | 可独立部署或云服务 | +| 生态 | 专注向量搜索 | 集成更多AI功能 | +| 学习成本 | 中等 | 较低 | +| 扩展性 | 优秀 | 良好 | + +## 后续优化建议 + +1. **连接池管理**: 实现MilvusClient连接池 +2. **异步操作**: 支持异步插入和查询 +3. **分片策略**: 大数据集的分片管理 +4. **监控告警**: 集成性能监控 +5. **备份恢复**: 数据备份和恢复机制 + +## 参考资料 + +- [Milvus官方文档](https://milvus.io/docs) +- [Milvus Java SDK](https://github.com/milvus-io/milvus-sdk-java) +- [向量数据库最佳实践](https://milvus.io/docs/performance_faq.md) \ No newline at end of file diff --git a/ruoyi-admin/src/main/resources/application-dev.yml b/ruoyi-admin/src/main/resources/application-dev.yml index 1fd51a25..c6e4e3f0 100644 --- a/ruoyi-admin/src/main/resources/application-dev.yml +++ b/ruoyi-admin/src/main/resources/application-dev.yml @@ -16,9 +16,9 @@ spring: master: type: ${spring.datasource.type} driverClassName: com.mysql.cj.jdbc.Driver - url: jdbc:mysql://127.0.0.1:3306/ruoyi-ai?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true + url: jdbc:mysql://127.0.0.1:3306/ruoyi-ai-github?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=true&serverTimezone=GMT%2B8&autoReconnect=true&rewriteBatchedStatements=true username: root - password: root + password: qxyg1010 hikari: # 最大连接池数量 diff --git a/ruoyi-modules-api/ruoyi-knowledge-api/pom.xml b/ruoyi-modules-api/ruoyi-knowledge-api/pom.xml index f8082a67..40a075e3 100644 --- a/ruoyi-modules-api/ruoyi-knowledge-api/pom.xml +++ b/ruoyi-modules-api/ruoyi-knowledge-api/pom.xml @@ -74,6 +74,12 @@ 1.19.6 + + io.milvus + milvus-sdk-java + 2.6.4 + + dev.langchain4j langchain4j-open-ai diff --git a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/VectorStoreService.java b/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/VectorStoreService.java index 21d2410d..ae0a227d 100644 --- a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/VectorStoreService.java +++ b/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/VectorStoreService.java @@ -1,5 +1,6 @@ package org.ruoyi.service; +import com.google.protobuf.ServiceException; import org.ruoyi.domain.bo.QueryVectorBo; import org.ruoyi.domain.bo.StoreEmbeddingBo; @@ -11,15 +12,15 @@ import java.util.List; */ public interface VectorStoreService { - void storeEmbeddings(StoreEmbeddingBo storeEmbeddingBo); + void storeEmbeddings(StoreEmbeddingBo storeEmbeddingBo) throws ServiceException; List getQueryVector(QueryVectorBo queryVectorBo); void createSchema(String vectorModelName, String kid,String modelName); - void removeById(String id,String modelName); + void removeById(String id,String modelName) throws ServiceException; - void removeByDocId(String docId, String kid); + void removeByDocId(String docId, String kid) throws ServiceException; - void removeByFid(String fid, String kid); + void removeByFid(String fid, String kid) throws ServiceException; } diff --git a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/strategy/impl/MilvusVectorStoreStrategy.java b/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/strategy/impl/MilvusVectorStoreStrategy.java index 25605629..540eefc8 100644 --- a/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/strategy/impl/MilvusVectorStoreStrategy.java +++ b/ruoyi-modules-api/ruoyi-knowledge-api/src/main/java/org/ruoyi/service/strategy/impl/MilvusVectorStoreStrategy.java @@ -1,8 +1,28 @@ package org.ruoyi.service.strategy.impl; +import com.google.gson.Gson; +import com.google.gson.JsonObject; import com.google.protobuf.ServiceException; import dev.langchain4j.data.embedding.Embedding; import dev.langchain4j.model.embedding.EmbeddingModel; +import io.milvus.v2.client.ConnectConfig; +import io.milvus.v2.client.MilvusClientV2; +import io.milvus.v2.common.DataType; +import io.milvus.v2.common.IndexParam; +import io.milvus.v2.service.collection.request.AddFieldReq; +import io.milvus.v2.service.collection.request.CreateCollectionReq; +import io.milvus.v2.service.collection.request.DescribeCollectionReq; +import io.milvus.v2.service.collection.request.DropCollectionReq; +import io.milvus.v2.service.collection.request.HasCollectionReq; +import io.milvus.v2.service.collection.response.DescribeCollectionResp; +import io.milvus.v2.service.vector.request.DeleteReq; +import io.milvus.v2.service.vector.request.InsertReq; +import io.milvus.v2.service.vector.request.SearchReq; +import io.milvus.v2.service.vector.request.data.BaseVector; +import io.milvus.v2.service.vector.request.data.FloatVec; +import io.milvus.v2.service.vector.response.DeleteResp; +import io.milvus.v2.service.vector.response.InsertResp; +import io.milvus.v2.service.vector.response.SearchResp; import lombok.extern.slf4j.Slf4j; import org.ruoyi.common.core.service.ConfigService; import org.ruoyi.domain.bo.QueryVectorBo; @@ -10,10 +30,7 @@ import org.ruoyi.domain.bo.StoreEmbeddingBo; import org.ruoyi.service.strategy.AbstractVectorStoreStrategy; import org.springframework.stereotype.Component; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.util.*; /** * Milvus向量库策略实现 @@ -24,8 +41,7 @@ import java.util.Map; @Component public class MilvusVectorStoreStrategy extends AbstractVectorStoreStrategy { - // Milvus客户端和相关配置 - // private MilvusClient milvusClient; + private MilvusClientV2 client; public MilvusVectorStoreStrategy(ConfigService configService) { super(configService); @@ -41,106 +57,89 @@ public class MilvusVectorStoreStrategy extends AbstractVectorStoreStrategy { log.info("Milvus创建schema: vectorModelName={}, kid={}, modelName={}", vectorModelName, kid, modelName); // 1. 获取Milvus配置 - String host = configService.getConfigValue("milvus", "host"); - String port = configService.getConfigValue("milvus", "port"); + String host = configService.getConfigValue("milvus", "url"); String collectionName = configService.getConfigValue("milvus", "collectionname") + kid; - // 2. 初始化Milvus客户端 - // ConnectParam connectParam = ConnectParam.newBuilder() - // .withHost(host) - // .withPort(Integer.parseInt(port)) - // .build(); - // milvusClient = new MilvusClient(connectParam); + ConnectConfig config = ConnectConfig.builder() + .uri(host) + .build(); + client = new MilvusClientV2(config); + + // 2. 检查集合是否存在 + HasCollectionReq hasCollectionReq = HasCollectionReq.builder() + .collectionName(collectionName) + .build(); - // 3. 检查集合是否存在,如果不存在则创建 - // HasCollectionParam hasCollectionParam = HasCollectionParam.newBuilder() - // .withCollectionName(collectionName) - // .build(); - // R hasCollectionResponse = milvusClient.hasCollection(hasCollectionParam); - // - // if (!hasCollectionResponse.getData()) { - // // 创建集合 - // List fieldsSchema = new ArrayList<>(); - // - // // 主键字段 - // fieldsSchema.add(FieldType.newBuilder() - // .withName("id") - // .withDataType(DataType.Int64) - // .withPrimaryKey(true) - // .withAutoID(true) - // .build()); - // - // // 文本字段 - // fieldsSchema.add(FieldType.newBuilder() - // .withName("text") - // .withDataType(DataType.VarChar) - // .withMaxLength(65535) - // .build()); - // - // // fid字段 - // fieldsSchema.add(FieldType.newBuilder() - // .withName("fid") - // .withDataType(DataType.VarChar) - // .withMaxLength(255) - // .build()); - // - // // kid字段 - // fieldsSchema.add(FieldType.newBuilder() - // .withName("kid") - // .withDataType(DataType.VarChar) - // .withMaxLength(255) - // .build()); - // - // // docId字段 - // fieldsSchema.add(FieldType.newBuilder() - // .withName("docId") - // .withDataType(DataType.VarChar) - // .withMaxLength(255) - // .build()); - // - // // 向量字段 - // fieldsSchema.add(FieldType.newBuilder() - // .withName("vector") - // .withDataType(DataType.FloatVector) - // .withDimension(1536) // 根据实际embedding维度调整 - // .build()); - // - // CreateCollectionParam createCollectionParam = CreateCollectionParam.newBuilder() - // .withCollectionName(collectionName) - // .withDescription("Knowledge base collection for " + kid) - // .withShardsNum(2) - // .withFieldTypes(fieldsSchema) - // .build(); - // - // R createCollectionResponse = milvusClient.createCollection(createCollectionParam); - // if (createCollectionResponse.getStatus() == R.Status.Success.getCode()) { - // log.info("Milvus集合创建成功: {}", collectionName); - // - // // 创建索引 - // IndexParam indexParam = IndexParam.newBuilder() - // .withCollectionName(collectionName) - // .withFieldName("vector") - // .withIndexType(IndexType.IVF_FLAT) - // .withMetricType(MetricType.L2) - // .withExtraParam("{\"nlist\":1024}") - // .build(); - // - // R createIndexResponse = milvusClient.createIndex(indexParam); - // if (createIndexResponse.getStatus() == R.Status.Success.getCode()) { - // log.info("Milvus索引创建成功: {}", collectionName); - // } else { - // log.error("Milvus索引创建失败: {}", createIndexResponse.getMessage()); - // } - // } else { - // log.error("Milvus集合创建失败: {}", createCollectionResponse.getMessage()); - // } - // } + Boolean hasCollection = client.hasCollection(hasCollectionReq); - log.info("Milvus schema创建完成: {}", collectionName); + if (!hasCollection) { + // 3. 创建集合schema + CreateCollectionReq.CollectionSchema schema = CreateCollectionReq.CollectionSchema.builder() + .build(); + + // 添加字段定义 + schema.addField(AddFieldReq.builder() + .fieldName("id") + .dataType(DataType.Int64) + .isPrimaryKey(true) + .autoID(true) + .build()); + + schema.addField(AddFieldReq.builder() + .fieldName("text") + .dataType(DataType.VarChar) + .maxLength(65535) + .build()); + + schema.addField(AddFieldReq.builder() + .fieldName("fid") + .dataType(DataType.VarChar) + .maxLength(255) + .build()); + + schema.addField(AddFieldReq.builder() + .fieldName("kid") + .dataType(DataType.VarChar) + .maxLength(255) + .build()); + + schema.addField(AddFieldReq.builder() + .fieldName("docId") + .dataType(DataType.VarChar) + .maxLength(255) + .build()); + + schema.addField(AddFieldReq.builder() + .fieldName("vector") + .dataType(DataType.FloatVector) + .dimension(1024) // 根据实际embedding维度调整 + .build()); + + // 4. 创建索引参数 + List indexParams = new ArrayList<>(); + indexParams.add(IndexParam.builder() + .fieldName("vector") + .indexType(IndexParam.IndexType.IVF_FLAT) + .metricType(IndexParam.MetricType.L2) + .extraParams(Map.of("nlist", 1024)) + .build()); + + // 5. 创建集合 + CreateCollectionReq createCollectionReq = CreateCollectionReq.builder() + .collectionName(collectionName) + .collectionSchema(schema) + .indexParams(indexParams) + .build(); + + client.createCollection(createCollectionReq); + log.info("Milvus集合创建成功: {}", collectionName); + } else { + log.info("Milvus集合已存在: {}", collectionName); + } } @Override - public void storeEmbeddings(StoreEmbeddingBo storeEmbeddingBo) { + public void storeEmbeddings(StoreEmbeddingBo storeEmbeddingBo) throws ServiceException { createSchema(storeEmbeddingBo.getVectorModelName(), storeEmbeddingBo.getKid(), storeEmbeddingBo.getVectorModelName()); EmbeddingModel embeddingModel = getEmbeddingModel(storeEmbeddingBo.getEmbeddingModelName(), @@ -155,48 +154,56 @@ public class MilvusVectorStoreStrategy extends AbstractVectorStoreStrategy { log.info("Milvus向量存储条数记录: " + chunkList.size()); long startTime = System.currentTimeMillis(); - // List fields = new ArrayList<>(); - // List textList = new ArrayList<>(); - // List fidListData = new ArrayList<>(); - // List kidList = new ArrayList<>(); - // List docIdList = new ArrayList<>(); - // List> vectorList = new ArrayList<>(); + // 准备批量插入数据 + List textList = new ArrayList<>(); + List fidListData = new ArrayList<>(); + List kidList = new ArrayList<>(); + List docIdList = new ArrayList<>(); + List> vectorList = new ArrayList<>(); for (int i = 0; i < chunkList.size(); i++) { String text = chunkList.get(i); String fid = fidList.get(i); Embedding embedding = embeddingModel.embed(text).content(); - // textList.add(text); - // fidListData.add(fid); - // kidList.add(kid); - // docIdList.add(docId); - // - // List vector = new ArrayList<>(); - // for (float f : embedding.vector()) { - // vector.add(f); - // } - // vectorList.add(vector); + textList.add(text); + fidListData.add(fid); + kidList.add(kid); + docIdList.add(docId); + + List vector = new ArrayList<>(); + for (float f : embedding.vector()) { + vector.add(f); + } + vectorList.add(vector); } - // fields.add(new InsertParam.Field("text", textList)); - // fields.add(new InsertParam.Field("fid", fidListData)); - // fields.add(new InsertParam.Field("kid", kidList)); - // fields.add(new InsertParam.Field("docId", docIdList)); - // fields.add(new InsertParam.Field("vector", vectorList)); - // - // InsertParam insertParam = InsertParam.newBuilder() - // .withCollectionName(collectionName) - // .withFields(fields) - // .build(); - // - // R insertResponse = milvusClient.insert(insertParam); - // if (insertResponse.getStatus() == R.Status.Success.getCode()) { - // log.info("Milvus向量存储成功,插入条数: {}", insertResponse.getData().getInsertCnt()); - // } else { - // log.error("Milvus向量存储失败: {}", insertResponse.getMessage()); - // throw new ServiceException("Milvus向量存储失败: " + insertResponse.getMessage()); - // } + // 构建插入数据 + List data = new ArrayList<>(); + Gson gson = new Gson(); + for (int i = 0; i < textList.size(); i++) { + JsonObject row = new JsonObject(); + row.addProperty("text", textList.get(i)); + row.addProperty("fid", fidListData.get(i)); + row.addProperty("kid", kidList.get(i)); + row.addProperty("docId", docIdList.get(i)); + row.add("vector", gson.toJsonTree(vectorList.get(i))); + data.add(row); + } + + // 执行插入 + InsertReq insertReq = InsertReq.builder() + .collectionName(collectionName) + .data(data) + .build(); + + InsertResp insertResp = client.insert(insertReq); + if (insertResp.getInsertCnt() > 0) { + log.info("Milvus向量存储成功,插入条数: {}", insertResp.getInsertCnt()); + } else { + log.error("Milvus向量存储失败"); + throw new ServiceException("Milvus向量存储失败"); + } long endTime = System.currentTimeMillis(); log.info("Milvus向量存储完成消耗时间:" + (endTime - startTime) / 1000 + "秒"); @@ -214,99 +221,95 @@ public class MilvusVectorStoreStrategy extends AbstractVectorStoreStrategy { List resultList = new ArrayList<>(); - // List searchOutputFields = List.of("text", "fid", "kid", "docId"); - // List> searchVectors = new ArrayList<>(); - // List queryVector = new ArrayList<>(); - // for (float f : queryEmbedding.vector()) { - // queryVector.add(f); - // } - // searchVectors.add(queryVector); - // - // SearchParam searchParam = SearchParam.newBuilder() - // .withCollectionName(collectionName) - // .withMetricType(MetricType.L2) - // .withOutFields(searchOutputFields) - // .withTopK(queryVectorBo.getMaxResults()) - // .withVectors(searchVectors) - // .withVectorFieldName("vector") - // .withParams("{\"nprobe\":10}") - // .build(); - // - // R searchResponse = milvusClient.search(searchParam); - // if (searchResponse.getStatus() == R.Status.Success.getCode()) { - // SearchResults searchResults = searchResponse.getData(); - // List queryResults = searchResults.getResults(); - // - // for (SearchResults.QueryResult queryResult : queryResults) { - // List rows = queryResult.getRows(); - // for (SearchResults.QueryResult.Row row : rows) { - // String text = (String) row.get("text"); - // resultList.add(text); - // } - // } - // } else { - // log.error("Milvus查询失败: {}", searchResponse.getMessage()); - // } + // 准备查询向量 + List searchVectors = new ArrayList<>(); + float[] queryVectorArray = new float[queryEmbedding.vector().length]; + for (int i = 0; i < queryEmbedding.vector().length; i++) { + queryVectorArray[i] = queryEmbedding.vector()[i]; + } + searchVectors.add(new FloatVec(queryVectorArray)); + + // 构建搜索请求 + SearchReq searchReq = SearchReq.builder() + .collectionName(collectionName) + .data(searchVectors) + .topK(queryVectorBo.getMaxResults()) + .outputFields(Arrays.asList("text", "fid", "kid", "docId")) + .build(); + + SearchResp searchResp = client.search(searchReq); + if (searchResp != null && searchResp.getSearchResults() != null) { + List> searchResults = searchResp.getSearchResults(); + + for (List results : searchResults) { + for (SearchResp.SearchResult result : results) { + Map entity = result.getEntity(); + String text = (String) entity.get("text"); + if (text != null) { + resultList.add(text); + } + } + } + } else { + log.error("Milvus查询失败或无结果"); + } return resultList; } @Override - public void removeById(String id, String modelName) { + public void removeById(String id, String modelName) throws ServiceException { String collectionName = configService.getConfigValue("milvus", "collectionname") + id; - // DropCollectionParam dropCollectionParam = DropCollectionParam.newBuilder() - // .withCollectionName(collectionName) - // .build(); - // - // R dropResponse = milvusClient.dropCollection(dropCollectionParam); - // if (dropResponse.getStatus() == R.Status.Success.getCode()) { - // log.info("Milvus集合删除成功: {}", collectionName); - // } else { - // log.error("Milvus集合删除失败: {}", dropResponse.getMessage()); - // throw new ServiceException("Milvus集合删除失败: " + dropResponse.getMessage()); - // } + // 删除整个集合 + DropCollectionReq dropCollectionReq = DropCollectionReq.builder() + .collectionName(collectionName) + .build(); - log.info("Milvus删除集合: {}", collectionName); + try { + client.dropCollection(dropCollectionReq); + log.info("Milvus集合删除成功: {}", collectionName); + } catch (Exception e) { + log.error("Milvus集合删除失败: {}", e.getMessage()); + throw new ServiceException("Milvus集合删除失败: " + e.getMessage()); + } } @Override - public void removeByDocId(String docId, String kid) { + public void removeByDocId(String docId, String kid) throws ServiceException { String collectionName = configService.getConfigValue("milvus", "collectionname") + kid; - // String expr = "docId == \"" + docId + "\""; - // DeleteParam deleteParam = DeleteParam.newBuilder() - // .withCollectionName(collectionName) - // .withExpr(expr) - // .build(); - // - // R deleteResponse = milvusClient.delete(deleteParam); - // if (deleteResponse.getStatus() == R.Status.Success.getCode()) { - // log.info("Milvus成功删除 docId={} 的所有向量数据,删除条数: {}", docId, deleteResponse.getData().getDeleteCnt()); - // } else { - // log.error("Milvus删除失败: {}", deleteResponse.getMessage()); - // } + String expr = "docId == \"" + docId + "\""; + DeleteReq deleteReq = DeleteReq.builder() + .collectionName(collectionName) + .filter(expr) + .build(); - log.info("Milvus删除docId={}的数据", docId); + try { + DeleteResp deleteResp = client.delete(deleteReq); + log.info("Milvus成功删除 docId={} 的所有向量数据,删除条数: {}", docId, deleteResp.getDeleteCnt()); + } catch (Exception e) { + log.error("Milvus删除失败: {}", e.getMessage()); + throw new ServiceException(e.getMessage()); + } } @Override - public void removeByFid(String fid, String kid) { + public void removeByFid(String fid, String kid) throws ServiceException { String collectionName = configService.getConfigValue("milvus", "collectionname") + kid; - // String expr = "fid == \"" + fid + "\""; - // DeleteParam deleteParam = DeleteParam.newBuilder() - // .withCollectionName(collectionName) - // .withExpr(expr) - // .build(); - // - // R deleteResponse = milvusClient.delete(deleteParam); - // if (deleteResponse.getStatus() == R.Status.Success.getCode()) { - // log.info("Milvus成功删除 fid={} 的所有向量数据,删除条数: {}", fid, deleteResponse.getData().getDeleteCnt()); - // } else { - // log.error("Milvus删除失败: {}", deleteResponse.getMessage()); - // } + String expr = "fid == \"" + fid + "\""; + DeleteReq deleteReq = DeleteReq.builder() + .collectionName(collectionName) + .filter(expr) + .build(); - log.info("Milvus删除fid={}的数据", fid); + try { + DeleteResp deleteResp = client.delete(deleteReq); + log.info("Milvus成功删除 fid={} 的所有向量数据,删除条数: {}", fid, deleteResp.getDeleteCnt()); + } catch (Exception e) { + log.error("Milvus删除失败: {}", e.getMessage()); + throw new ServiceException(e.getMessage()); + } } } \ No newline at end of file