# aiStudy **Repository Path**: zzqx/ai-study ## Basic Information - **Project Name**: aiStudy - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-02-10 - **Last Updated**: 2026-02-13 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README Here is the formatted and beautified Markdown file. ```markdown # Milvus ORM 工具类使用文档 > **版本:** 1.0 > **基于组件:** `MilvusEntityRepository`, `MilvusSchemaCreator`, `MilvusMetadataSearchUtil` --- ## 📑 目录 1. [简介](#1-简介) 2. [快速开始](#2-快速开始) 3. [注解说明](#3-注解说明) 4. [初始化与集合管理](#4-初始化与集合管理) 5. [CRUD 操作指南](#5-crud-操作指南) 6. [向量搜索与混合检索](#6-向量搜索与混合检索) 7. [常见问题与注意事项](#7-常见问题与注意事项) --- ## 1. 简介 本工具包提供了一套基于 Java 注解的 **Milvus ORM** (对象关系映射) 解决方案。它允许开发者像操作普通 Java 对象一样操作 Milvus 向量数据库,无需手动构建复杂的 Map 或 JSON 参数。 ### 核心组件 | 组件名称 | 职责描述 | | :--- | :--- | | **MilvusEntityRepository** | 对外提供的核心接口,负责实体的增删改查。 | | **MilvusSchemaCreator** | 负责根据实体类注解自动创建 Milvus Collection 和索引。 | | **MilvusMetadataSearchUtil** | 底层通用工具类,处理 Map 与 Milvus 的交互。 | --- ## 2. 快速开始 ### 2.1 依赖配置 确保项目中已引入 Milvus SDK (v2.x) 和相关依赖 (Lombok, Gson, Spring Boot等)。 ### 2.2 配置文件 在 `application.yml` 中配置 Milvus 连接地址: ```yaml milvus: host: localhost port: 19530 ``` ### 2.3 定义实体类 使用 `@MilvusEntity` 和 `@MilvusField` 注解定义你的数据模型。 **示例:** ```java @Data @MilvusEntity(collectionName = "products", description = "商品向量库") public class Product { @MilvusField(isPrimaryKey = true, autoID = false, dataType = FieldDataType.Int64) private Long id; @MilvusField(dataType = FieldDataType.VarChar, maxLength = 255) private String name; @MilvusField(dataType = FieldDataType.FloatVector, dimension = 128) private List embedding; } ``` --- ## 3. 注解说明 ### 3.1 @MilvusEntity (类级别) 用于标记一个 Java 类为 Milvus 的集合映射。 | 属性 | 类型 | 默认值 | 描述 | | :--- | :--- | :--- | :--- | | `collectionName` | String | 类名小写 | 集合名称 | | `databaseName` | String | "default" | 数据库名称 | | `description` | String | - | 集合描述 | | `enableDynamicField` | boolean | true | 是否开启动态字段 | | `indexType` | String | "IVF_FLAT" | 向量索引类型 | | `metricType` | String | "COSINE" | 向量度量类型 | ### 3.2 @MilvusField (字段级别) 用于标记 Java 字段为 Milvus 中的列。 | 属性 | 类型 | 默认值 | 描述 | | :--- | :--- | :--- | :--- | | `fieldName` | String | Java属性名 | 字段名称 | | `isPrimaryKey` | boolean | false | 是否为主键 | | `autoID` | boolean | false | 是否自动生成 ID (开启后无法手动指定ID插入) | | `dataType` | FieldType | - | 字段数据类型 (参见枚举) | | `dimension` | int | - | 向量维度 (仅向量类型有效) | | `maxLength` | int | - | 最大长度 (仅 VarChar 有效) | | `description` | String | - | 字段描述 | ### 3.3 FieldDataType (枚举) 支持的数据类型: * **基础类型**: `Bool`, `Int8`, `Int16`, `Int32`, `Int64`, `Float`, `Double` * **字符串/对象**: `VarChar`, `JSON`, `Array` * **向量类型**: `FloatVector`, `BinaryVector`, `SparseFloatVector` --- ## 4. 初始化与集合管理 在应用启动或需要创建集合时,调用 `MilvusSchemaCreator`。 ```java @Autowired private MilvusSchemaCreator schemaCreator; public void initCollection() { // 根据实体类创建集合 (如果不存在) // 它会自动创建字段、主键索引和向量索引 schemaCreator.createCollectionFromClass(Product.class); } ``` > **⚠️ 注意:** > * 如果集合已存在,该方法会自动跳过。 > * 如果修改了实体类的结构 (如增加字段),通常需要删除旧集合并重新运行此方法。 --- ## 5. CRUD 操作指南 注入 Repository: ```java @Autowired private MilvusEntityRepository repository; ``` ### 5.1 插入 ```java // 单条插入 Product p = new Product(); p.setId(1L); p.setName("iPhone 15"); p.setEmbedding(Arrays.asList(0.1f, 0.2f, ...)); // 128维向量 repository.insert(p); // 批量插入 List products = ...; repository.insertBatch(products); ``` > **⚠️ 注意:** > * 如果实体类设置了 `autoID = false`,插入前必须手动给 ID 赋值。 > * 如果设置了 `autoID = true`,插入时不要设置 ID,Milvus 会自动生成。 ### 5.2 更新 / 插入 ```java // Upsert: 存在则更新,不存在则插入 // 前提: 实体类必须包含主键值,且 Milvus 集合不能开启 autoID repository.upsert(p); // 批量 Upsert repository.upsertBatch(products); ``` ### 5.3 删除 ```java // 根据 ID 删除 repository.deleteById(Product.class, 1L); // 批量删除 List ids = Arrays.asList(1L, 2L, 3L); repository.deleteByIds(Product.class, ids); // 根据条件删除 (标量过滤) ScalarFilter filter = ScalarFilter.builder() .equalConditions(Map.of("status", "inactive")) .build(); repository.deleteByFilter(Product.class, filter); // 根据表达式字符串删除 repository.deleteByExpression(Product.class, "price < 100"); ``` ### 5.4 查询 ```java // 根据 ID 查询单条 Product p = repository.getById(Product.class, 1L); // 根据 ID 批量查询 List list = repository.getByIds(Product.class, Arrays.asList(1L, 2L)); // 根据标量条件查询 ScalarFilter filter = MilvusMetadataSearchUtil.eq("category", "electronics"); List electronics = repository.query(Product.class, filter); // 复杂条件查询 ScalarFilter complexFilter = MilvusMetadataSearchUtil.and( MilvusMetadataSearchUtil.eq("brand", "Apple"), MilvusMetadataSearchUtil.between("price", 500, 2000) ); List apples = repository.query(Product.class, complexFilter); // 自定义表达式查询 List results = repository.queryByExpression(Product.class, "name like '%Pro%'", 10L); ``` --- ## 6. 向量搜索与混合检索 ### 6.1 向量搜索 (基础) ```java List queryVector = ...; // 128维查询向量 // 构建搜索选项 MilvusMetadataSearchUtil.SearchOptions options = MilvusMetadataSearchUtil.SearchOptions.builder() .topK(10) // 返回最相似的10条 .metricType(MetricType.COSINE) // 相似度度量 .build(); // 执行搜索 // null vectorField 表示自动查找实体类中的向量字段 // null filter 表示不带标量过滤 List> results = repository.hybridSearch( Product.class, queryVector, null, // vectorField null, // filter options ); // 处理结果 for (SearchResult res : results) { System.out.println("Score: " + res.getScore()); System.out.println("Name: " + res.getEntity().getName()); } ``` ### 6.2 混合搜索 (向量 + 标量过滤) **场景**: 搜索相似商品,但必须是 "Apple" 品牌且价格在 500 以上。 ```java List queryVector = ...; // 1. 构建标量过滤器 ScalarFilter filter = MilvusMetadataSearchUtil.and( MilvusMetadataSearchUtil.eq("brand", "Apple"), MilvusMetadataSearchUtil.gt("price", 500) // 或者使用自定义表达式: // ScalarFilter.builder().customExpression("brand == 'Apple' && price > 500").build() ); // 2. 执行搜索 List> results = repository.hybridSearch( Product.class, queryVector, null, filter, // 传入过滤器 MilvusMetadataSearchUtil.SearchOptions.builder().topK(5).build() ); ``` ### 6.3 ScalarFilter 常用构建方法 | 方法 | 描述 | | :--- | :--- | | `eq(field, value)` | 等于 | | `in(field, values)` | 在列表中 | | `between(field, min, max)` | 在范围内 | | `like(field, pattern)` | 模糊匹配 | | `contains(field, substr)` | 包含字符串 | | `and(filters...)` | 逻辑且 | | `or(filters...)` | 逻辑或 | --- ## 7. 常见问题与注意事项 ### Q1: 报错 "upsert can not assign primary field data when auto id enabled" **原因**: 尝试向一个开启了自动生成ID (`autoID=true`) 的集合中手动写入 ID。 **解决**: 1. 修改实体类注解 `@MilvusField(autoID = false)`。 2. 在代码中手动为 ID 赋值 (如使用雪花算法)。 3. 删除旧集合并使用 `MilvusSchemaCreator` 重新创建集合。 ### Q2: 搜索返回的实体对象属性都是 null,只有 ID 有值? **原因**: 默认情况下 Milvus 搜索只返回 ID。 **解决**: 本工具包的 `MilvusEntityRepository.hybridSearch` 已自动处理了 `outputFields`,会自动请求并填充实体属性。如果仍有问题,请确保实体类字段的注解名称与 Milvus 中实际字段名一致。 ### Q3: 搜索结果中包含 Embedding 向量数据,导致传输变慢? **原因**: 可能配置了返回动态字段或手动将向量字段加入了 `outputFields`。 **解决**: `MilvusEntityRepository` 内部会自动排除向量字段。如果您是手动调用底层 `MilvusMetadataSearchUtil`,请确保 `outputFields` 列表中不包含向量字段名。 ### Q4: 如何处理 JSON 字段? **解决**: 在实体类中定义为 `String` 类型或 `Object` 类型,注解设置为 `dataType = FieldDataType.JSON`。Milvus 会将其存储为 JSON 格式。 ### Q5: 修改了实体类结构 (增删字段) 怎么办? **解决**: Milvus 不支持直接修改 Schema。您需要删除现有的 Collection,然后修改 Java 实体类注解,再调用 `MilvusSchemaCreator` 重新创建 Collection。 > **⚠️ 生产环境请务必注意数据备份。** --- **文档结束** ```