!1 新增接口相关注释

Merge pull request !1 from 余路/main
This commit is contained in:
xgc 2024-05-13 08:33:14 +00:00 committed by Gitee
commit 632916a299
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
2 changed files with 101 additions and 21 deletions

View File

@ -25,25 +25,45 @@ import java.util.Map;
**/
public class MilvusEntityConverter {
/**
* 将Java实体类转换为MilvusEntity对象
* 该过程涉及读取实体类上的@MilvusCollection和@MilvusField注解根据注解信息构建MilvusEntity对象
* 同时缓存有关实体类与字段的映射信息和索引参数以便后续使用
*
* @param entityClass 需要转换的Java实体类的Class对象
* @return 转换后的MilvusEntity对象包含了Milvus表的结构信息和索引参数
* @throws IllegalArgumentException 如果实体类没有@MilvusCollection注解则抛出异常
*/
public static MilvusEntity convert(Class<?> entityClass) {
MilvusEntity milvus=new MilvusEntity();
// 获取实体类上的@MilvusCollection注解校验其存在性
MilvusCollection collectionAnnotation = entityClass.getAnnotation(MilvusCollection.class);
if (collectionAnnotation == null) {
throw new IllegalArgumentException("Entity must be annotated with @MilvusCollection");
}
// 从注解中读取集合名称
String collectionName = collectionAnnotation.name();
milvus.setCollectionName(collectionName);
// 初始化字段列表和索引参数列表
List<AddFieldReq> milvusFields = new ArrayList<>();
List<IndexParam> indexParams=new ArrayList<>();
// 用于存储属性与函数映射的缓存
PropertyCache propertyCache=new PropertyCache();
// 遍历实体类的所有字段读取@MilvusField注解信息
for (Field field : entityClass.getDeclaredFields()) {
MilvusField fieldAnnotation = field.getAnnotation(MilvusField.class);
if (fieldAnnotation != null) {
// 处理字段名优先使用注解中的字段名若无则用反射获取的字段名
String fieldName = fieldAnnotation.name().isEmpty() ? field.getName() : fieldAnnotation.name();
// 缓存属性名与函数名的映射
propertyCache.functionToPropertyMap.put(field.getName(),fieldName);
// 处理主键字段
if (fieldAnnotation.isPrimaryKey()) {
CollectionToPrimaryCache.collectionToPrimary.put(collectionName,fieldName);
}
// 构建Milvus字段描述
AddFieldReq.AddFieldReqBuilder<?, ?> builder = AddFieldReq.builder()
.fieldName(fieldName)
.dataType(fieldAnnotation.dataType())
@ -51,9 +71,11 @@ public class MilvusEntityConverter {
.isPartitionKey(fieldAnnotation.isPartitionKey())
.elementType(fieldAnnotation.elementType())
.autoID(fieldAnnotation.autoID());
// 如果存在描述则添加
if(StringUtils.isNotEmpty(fieldAnnotation.description())){
builder.description(fieldAnnotation.description());
}
// 处理向量字段的维度数组字段的最大长度hash表的最大容量
if(fieldAnnotation.dimension()>0){
builder.dimension(fieldAnnotation.dimension());
}
@ -63,37 +85,53 @@ public class MilvusEntityConverter {
if(fieldAnnotation.maxCapacity() > 0){
builder.maxCapacity(fieldAnnotation.maxCapacity());
}
// 构建字段对象并添加到列表
AddFieldReq milvusField = builder.build();
milvusFields.add(milvusField);
// 构建IndexParam对象
// 根据字段信息构建索引参数对象
IndexParam indexParam = createIndexParam(field,fieldName);
if(indexParam!=null){
indexParams.add(indexParam);
}
}
}
// 设置Milvus字段和索引参数
milvus.setMilvusFields(milvusFields);
milvus.setIndexParams(indexParams);
//缓存
// 缓存转换结果和集合信息
ConversionCache conversionCache=new ConversionCache();
conversionCache.setMilvusEntity(milvus);
conversionCache.setCollectionName(collectionName);
conversionCache.setPropertyCache(propertyCache);
MilvusCache.milvusCache.put(entityClass,conversionCache);
return milvus;
}
/**
* 根据字段信息和字段名称创建索引参数对象
*
* @param field 字段对象需要包含MilvusIndex注解以用于索引配置
* @param fieldName 字段名称用于构建索引参数时作为名称备用
* @return IndexParam 索引参数对象如果字段没有MilvusIndex注解则返回null
*/
private static IndexParam createIndexParam(Field field,String fieldName) {
// 尝试获取字段上的MilvusIndex注解用于后续索引参数的构建
MilvusIndex fieldAnnotation = field.getAnnotation(MilvusIndex.class);
if (fieldAnnotation == null) {
return null;
}
// 初始化额外参数映射用于存储由extraParams注解提供的额外参数
Map<String,Object> map=new HashMap<>();
ExtraParam[] extraParams = fieldAnnotation.extraParams();
for (ExtraParam extraParam : extraParams) {
map.put(extraParam.key(),extraParam.value());
}
// 使用收集到的参数构建索引参数对象
return IndexParam.builder()
.indexName(fieldAnnotation.indexName().isEmpty() ? fieldName : fieldAnnotation.indexName())
.fieldName(fieldName)
@ -104,4 +142,4 @@ public class MilvusEntityConverter {
}
}
}

View File

@ -23,41 +23,55 @@ public class SearchRespConverter {
private static final ObjectMapper objectMapper = new ObjectMapper();
/**
* 将SearchResp对象转换为自定义的MilvusResp对象其中SearchResp是Milvus搜索响应的内部结构
* 而MilvusResp是对外提供的统一响应格式该方法主要涉及将搜索结果中的每个实体从Map形式转换为指定的Java实体类T
*
* @param searchResp Milvus搜索操作的原始响应对象包含搜索结果的详细信息
* @param entityType 指定的Java实体类类型用于将搜索结果的每个实体转换为该类型
* @return 转换后的MilvusResp对象其中包含了列表形式的搜索结果以及操作是否成功的标志
*/
public static <T> MilvusResp<List<MilvusResult<T>>> convertSearchRespToMilvusResp(SearchResp searchResp, Class<T> entityType) {
// 从缓存中获取对应实体类型的转换缓存和属性缓存
ConversionCache conversionCache = MilvusCache.milvusCache.get(entityType);
PropertyCache propertyCache = conversionCache.getPropertyCache();
// 获取原始搜索结果列表并将其转换为MilvusResult<T>类型的列表
List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
// 将searchResults中的每个SearchResult转换为MilvusResult<T>
List<List<MilvusResult<T>>> milvusResults = searchResults.stream()
.map(innerList -> innerList.stream()
.map(searchResult -> {
try {
// 使用ObjectMapper将Map<String, Object>转换为Java实体类T
// 根据属性缓存将实体Map中的键转换为对应的Java实体类字段名
Map<String, Object> entityMap = searchResult.getEntity();
Map<String, Object> entityMap2=new HashMap<>();
for (Map.Entry<String, Object> entry : entityMap.entrySet()) {
String key = propertyCache.findKeyByValue(entry.getKey());
entityMap2.put(key,entry.getValue());
}
// 将转换后的Map转换为Java实体类T
T entity = objectMapper.convertValue(entityMap2, entityType);
// 创建MilvusResult对象并设置相关字段
MilvusResult<T> tMilvusResult = new MilvusResult<>();
tMilvusResult.setId(searchResult.getId());
tMilvusResult.setDistance(searchResult.getDistance());
tMilvusResult.setEntity(entity);
return tMilvusResult;
} catch (IllegalArgumentException e) {
// 处理转换错误
// 抛出转换过程中的异常
throw new RuntimeException(e);
}
})
.collect(Collectors.toList()))
.collect(Collectors.toList());
List<MilvusResult<T>> results = milvusResults
.stream() // 从原始列表开始流操作
.flatMap(List::stream) // 使用 flatMap 将嵌套列表展平
.collect(Collectors.toList());// 收集结果到一个新的列表中
// 创建MilvusResp对象并设置结果和成功标志
// 将嵌套的列表展平为单个列表
List<MilvusResult<T>> results = milvusResults
.stream()
.flatMap(List::stream)
.collect(Collectors.toList());
// 创建并填充MilvusResp对象
MilvusResp<List<MilvusResult<T>>> milvusResp = new MilvusResp<>();
milvusResp.setData(results);
milvusResp.setSuccess(true);
@ -65,42 +79,70 @@ public class SearchRespConverter {
return milvusResp;
}
/**
* 将Get响应转换为Milvus响应的通用方法
* @param getResp Get操作的响应对象可以是QueryResp或GetResp类型
* @param entityType 实体类型用于泛型结果的类型转换
* @return 返回一个包含Milvus结果列表的MilvusResp对象
*/
public static <T> MilvusResp<List<MilvusResult<T>>> convertGetRespToMilvusResp(QueryResp getResp, Class<T> entityType) {
// 从QueryResp中提取查询结果
List<QueryResp.QueryResult> queryResults = getResp.getQueryResults();
return convertQuery(queryResults,entityType);
return convertQuery(queryResults, entityType);
}
/**
* 将Get响应转换为Milvus响应的通用方法
* @param getResp Get操作的响应对象可以是QueryResp或GetResp类型
* @param entityType 实体类型用于泛型结果的类型转换
* @return 返回一个包含Milvus结果列表的MilvusResp对象
*/
public static <T> MilvusResp<List<MilvusResult<T>>> convertGetRespToMilvusResp(GetResp getResp, Class<T> entityType) {
// 从GetResp中提取结果
List<QueryResp.QueryResult> getResults = getResp.getResults;
return convertQuery(getResults,entityType);
return convertQuery(getResults, entityType);
}
private static <T> MilvusResp<List<MilvusResult<T>>> convertQuery(List<QueryResp.QueryResult> getResults, Class<T> entityType){
// 解析GetResp中的查询结果
/**
* 将查询结果转换为指定类型的实体列表
*
* @param getResults 查询结果列表来自Milvus数据库的查询响应
* @param entityType 需要转换成的实体类型指定了转换的目标
* @return MilvusResp对象包含转换后的实体列表每个实体都包装在一个MilvusResult对象中同时设置成功状态为true
*/
private static <T> MilvusResp<List<MilvusResult<T>>> convertQuery(List<QueryResp.QueryResult> getResults, Class<T> entityType){
// 初始化转换缓存和属性缓存用于帮助将查询结果映射到Java实体
ConversionCache conversionCache = MilvusCache.milvusCache.get(entityType);
PropertyCache propertyCache = conversionCache.getPropertyCache();
List<T> entities = new ArrayList<>();
// 遍历每个查询结果并将它们映射到Java实体类T的实例
// 遍历每个查询结果映射到对应的Java实体
for (QueryResp.QueryResult queryResult : getResults) {
Map<String, Object> entityMap = queryResult.getEntity();
Map<String, Object> entityMap2=new HashMap<>();
// 通过属性缓存转换键名以适应Java实体的字段命名
for (Map.Entry<String, Object> entry : entityMap.entrySet()) {
String key = propertyCache.findKeyByValue(entry.getKey());
entityMap2.put(key,entry.getValue());
}
// 假设有一个方法可以从Map映射到实体类T这个方法需要自定义实现
// 使用转换工具将映射后的Map转换为指定类型的实体
T entity = objectMapper.convertValue(entityMap2, entityType);
entities.add(entity);
}
// 将转换后的实体列表包装成MilvusResult对象并收集到一个新的列表中
List<MilvusResult<T>> results = entities.stream().map(v -> {
MilvusResult<T> vo = new MilvusResult<>();
vo.setEntity(v);
vo.setDistance(0.0f);
vo.setDistance(0.0f); // 设置距离为0.0f因为当前上下文未提供实际距离信息
return vo;
}).collect(Collectors.toList());
// 创建MilvusResp对象并将实体列表作为其数据部分
// 构建并返回一个包含转换结果的MilvusResp对象标记操作成功
MilvusResp<List<MilvusResult<T>>> milvusResp = new MilvusResp<>();
milvusResp.setData(results);
milvusResp.setSuccess(true);
// 返回MilvusResp对象
return milvusResp;
}
}
}