diff --git a/milvus-plus-core/src/main/java/org/dromara/milvus/plus/cache/PropertyCache.java b/milvus-plus-core/src/main/java/org/dromara/milvus/plus/cache/PropertyCache.java index c319d24..7ecd94a 100644 --- a/milvus-plus-core/src/main/java/org/dromara/milvus/plus/cache/PropertyCache.java +++ b/milvus-plus-core/src/main/java/org/dromara/milvus/plus/cache/PropertyCache.java @@ -1,7 +1,10 @@ package org.dromara.milvus.plus.cache; import java.util.HashMap; +import java.util.HashSet; import java.util.Map; +import java.util.Set; + /** * @author xgc **/ @@ -13,6 +16,9 @@ public class PropertyCache { public Map methodToPropertyMap = new HashMap<>(); //属性get方法名称->集合属性名称 + public Set metaFunctionSet = new HashSet<>(); //动态字段属性名称 + + public Map metaMethodMap = new HashMap<>(); //属性get方法名称 // 根据值查找第一个匹配的键 public String findKeyByValue(String value) { diff --git a/milvus-plus-core/src/main/java/org/dromara/milvus/plus/converter/MilvusConverter.java b/milvus-plus-core/src/main/java/org/dromara/milvus/plus/converter/MilvusConverter.java index d05f562..2c0e917 100644 --- a/milvus-plus-core/src/main/java/org/dromara/milvus/plus/converter/MilvusConverter.java +++ b/milvus-plus-core/src/main/java/org/dromara/milvus/plus/converter/MilvusConverter.java @@ -96,6 +96,8 @@ public class MilvusConverter { if (Objects.isNull(fieldAnnotation)) { if (collectionAnnotation.enableDynamicField()) { propertyCache.functionToPropertyMap.put("$meta", "$meta"); + propertyCache.metaFunctionSet.add(field.getName()); + propertyCache.metaMethodMap.put(getGetMethodName(field), field.getName()); } continue; } diff --git a/milvus-plus-core/src/main/java/org/dromara/milvus/plus/converter/SearchRespConverter.java b/milvus-plus-core/src/main/java/org/dromara/milvus/plus/converter/SearchRespConverter.java index 0cb51f6..7cc2874 100644 --- a/milvus-plus-core/src/main/java/org/dromara/milvus/plus/converter/SearchRespConverter.java +++ b/milvus-plus-core/src/main/java/org/dromara/milvus/plus/converter/SearchRespConverter.java @@ -27,7 +27,7 @@ public class SearchRespConverter { * @param entityType 指定的Java实体类类型,用于将搜索结果的每个实体转换为该类型。 * @return 转换后的MilvusResp对象,其中包含了列表形式的搜索结果以及操作是否成功的标志。 */ - public static MilvusResp>> convertSearchRespToMilvusResp(SearchResp searchResp, Class entityType) { + public static MilvusResp>> convertSearchRespToMilvusResp(SearchResp searchResp, Class entityType, List outputMetaFields) { // 从缓存中获取对应实体类型的转换缓存和属性缓存 ConversionCache conversionCache = MilvusCache.milvusCache.get(entityType.getName()); PropertyCache propertyCache = conversionCache.getPropertyCache(); @@ -46,7 +46,11 @@ public class SearchRespConverter { if (entry.getValue() == null) { continue; } - entityMap.putAll(GsonUtil.fromJsonToMap(entry.getValue().toString())); + Map metaMap = GsonUtil.fromJsonToMap(entry.getValue().toString()); + //metaFunctionSet 类型匹配,并完成 map 放入 entityMap 的操作 + metaMap.entrySet().stream() + .filter(mapEntry -> propertyCache.metaFunctionSet.contains(String.valueOf(mapEntry.getKey())) && outputMetaFields.contains(mapEntry.getKey())) + .forEach(mapEntry -> entityMap.put(String.valueOf(mapEntry.getKey()), mapEntry.getValue())); } else if(key!=null){ Object value = entry.getValue(); entityMap.put(key,value); @@ -75,10 +79,10 @@ public class SearchRespConverter { * @param entityType 实体类型,用于泛型结果的类型转换。 * @return 返回一个包含Milvus结果列表的MilvusResp对象。 */ - public static MilvusResp>> convertGetRespToMilvusResp(QueryResp getResp, Class entityType) { + public static MilvusResp>> convertGetRespToMilvusResp(QueryResp getResp, Class entityType, List outputMetaFields) { // 从QueryResp中提取查询结果 List queryResults = getResp.getQueryResults(); - return convertQuery(queryResults, entityType); + return convertQuery(queryResults, entityType, outputMetaFields); } public static MilvusResp convertGetRespToCount(QueryResp getResp) { // 从QueryResp中提取查询结果 @@ -92,10 +96,10 @@ public class SearchRespConverter { * @param entityType 实体类型,用于泛型结果的类型转换。 * @return 返回一个包含Milvus结果列表的MilvusResp对象。 */ - public static MilvusResp>> convertGetRespToMilvusResp(GetResp getResp, Class entityType) { + public static MilvusResp>> convertGetRespToMilvusResp(GetResp getResp, Class entityType, List outputMetaFields) { // 从GetResp中提取结果 List getResults = getResp.getResults; - return convertQuery(getResults, entityType); + return convertQuery(getResults, entityType, outputMetaFields); } @@ -106,7 +110,7 @@ public class SearchRespConverter { * @param entityType 需要转换成的实体类型,指定了转换的目标。 * @return MilvusResp对象,包含转换后的实体列表。每个实体都包装在一个MilvusResult对象中,同时设置成功状态为true。 */ - private static MilvusResp>> convertQuery(List getResults, Class entityType){ + private static MilvusResp>> convertQuery(List getResults, Class entityType, List outputFields){ // 初始化转换缓存和属性缓存,用于帮助将查询结果映射到Java实体 ConversionCache conversionCache = MilvusCache.milvusCache.get(entityType.getName()); PropertyCache propertyCache = conversionCache.getPropertyCache(); @@ -119,7 +123,11 @@ public class SearchRespConverter { // 通过属性缓存转换键名,以适应Java实体的字段命名 for (Map.Entry entry : entityMap.entrySet()) { String key = propertyCache.findKeyByValue(entry.getKey()); - if(key!=null){ + if (conversionCache.getMilvusEntity().getEnableDynamicField() + && propertyCache.metaFunctionSet.contains(entry.getKey()) + && outputFields.contains(entry.getKey())) { + entityMap2.put(String.valueOf(entry.getKey()), entry.getValue()); + } else if(key!=null){ Object value = entry.getValue(); entityMap2.put(key,value); } diff --git a/milvus-plus-core/src/main/java/org/dromara/milvus/plus/core/conditions/LambdaQueryWrapper.java b/milvus-plus-core/src/main/java/org/dromara/milvus/plus/core/conditions/LambdaQueryWrapper.java index 2999fe9..23222b0 100644 --- a/milvus-plus-core/src/main/java/org/dromara/milvus/plus/core/conditions/LambdaQueryWrapper.java +++ b/milvus-plus-core/src/main/java/org/dromara/milvus/plus/core/conditions/LambdaQueryWrapper.java @@ -36,6 +36,7 @@ import java.util.stream.Collectors; public class LambdaQueryWrapper extends AbstractChainWrapper implements Wrapper, T> { private ConversionCache conversionCache; private List outputFields; + private List outputMetaFields; private Class entityType; private String collectionName; private String collectionAlias; @@ -977,18 +978,18 @@ public class LambdaQueryWrapper extends AbstractChainWrapper implements Wr HybridSearchReq hybridSearchReq = buildHybrid(); log.info("Build HybridSearch Param--> {}", GsonUtil.toJson(hybridSearchReq)); SearchResp searchResp = client.hybridSearch(hybridSearchReq); - return SearchRespConverter.convertSearchRespToMilvusResp(searchResp, entityType); + return SearchRespConverter.convertSearchRespToMilvusResp(searchResp, entityType, outputMetaFields); } if (!vectors.isEmpty()) { SearchReq searchReq = buildSearch(); log.info("Build Search Param--> {}", GsonUtil.toJson(searchReq)); SearchResp searchResp = client.search(searchReq); - return SearchRespConverter.convertSearchRespToMilvusResp(searchResp, entityType); + return SearchRespConverter.convertSearchRespToMilvusResp(searchResp, entityType, outputMetaFields); } else { QueryReq queryReq = buildQuery(); log.info("Build Query param--> {}", GsonUtil.toJson(queryReq)); QueryResp queryResp = client.query(queryReq); - return SearchRespConverter.convertGetRespToMilvusResp(queryResp, entityType); + return SearchRespConverter.convertGetRespToMilvusResp(queryResp, entityType, outputMetaFields); } }, "collection not loaded", @@ -1002,7 +1003,15 @@ public class LambdaQueryWrapper extends AbstractChainWrapper implements Wr public MilvusResp>> query(FieldFunction... outputFields) throws MilvusException { List otf = new ArrayList<>(); for (FieldFunction outputField : outputFields) { - otf.add(outputField.getFieldName(outputField)); + String methodName = outputField.getSerializedLambda(outputField).getImplMethodName(); + if (conversionCache.getMilvusEntity().getEnableDynamicField() && + conversionCache.getPropertyCache().metaMethodMap.containsKey(methodName)){ + outputMetaFields = Optional.ofNullable(outputMetaFields).orElse(new ArrayList<>()); + outputMetaFields.add(conversionCache.getPropertyCache().metaMethodMap.get(methodName)); + otf.add("$meta"); + } else { + otf.add(outputField.getFieldName(outputField)); + } } this.outputFields = otf; return query(); @@ -1027,7 +1036,19 @@ public class LambdaQueryWrapper extends AbstractChainWrapper implements Wr } public MilvusResp>> query(String... outputFields) throws MilvusException { - this.outputFields = Arrays.stream(outputFields).collect(Collectors.toList()); + this.outputFields = Arrays.stream(outputFields) + .map(field -> { + String milvusField = conversionCache.getPropertyCache().functionToPropertyMap.get(field); + if (milvusField == null && + conversionCache.getMilvusEntity().getEnableDynamicField() && + conversionCache.getPropertyCache().metaFunctionSet.contains(field)) { + outputMetaFields = Optional.ofNullable(outputMetaFields).orElse(new ArrayList<>()); + outputMetaFields.add(field); + return "$meta"; + } + return milvusField; + }) + .collect(Collectors.toList()); return query(); } @@ -1041,7 +1062,7 @@ public class LambdaQueryWrapper extends AbstractChainWrapper implements Wr GetReq getReq = builder.build(); GetResp getResp = client.get(getReq); - return SearchRespConverter.convertGetRespToMilvusResp(getResp, entityType); + return SearchRespConverter.convertGetRespToMilvusResp(getResp, entityType, outputMetaFields); } @Override