mirror of
https://gitee.com/dromara/MilvusPlus.git
synced 2025-12-06 08:58:26 +08:00
!56 态字段查询与映射转换 & 优化分区名称设置前的集合非空判断
Merge pull request !56 from CodeYuan-Y/main
This commit is contained in:
commit
d15e1f8c51
@ -54,7 +54,7 @@ public class CollectionSchemaBuilder {
|
||||
}
|
||||
|
||||
public void addNumPartitions(Integer numPartitions){
|
||||
if (numPartitions < 1) {
|
||||
if (numPartitions == null || numPartitions < 1) {
|
||||
return;
|
||||
}
|
||||
this.numPartitions=numPartitions;
|
||||
|
||||
@ -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<String, String> methodToPropertyMap = new HashMap<>(); //属性get方法名称->集合属性名称
|
||||
|
||||
public Set<String> metaFunctionSet = new HashSet<>(); //动态字段属性名称
|
||||
|
||||
public Map<String, String> metaMethodMap = new HashMap<>(); //属性get方法名称
|
||||
|
||||
// 根据值查找第一个匹配的键
|
||||
public String findKeyByValue(String value) {
|
||||
|
||||
@ -94,6 +94,11 @@ public class MilvusConverter {
|
||||
for (Field field : fields) {
|
||||
MilvusField fieldAnnotation = field.getAnnotation(MilvusField.class);
|
||||
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;
|
||||
}
|
||||
// 处理字段名,优先使用注解中的字段名,若无则用反射获取的字段名
|
||||
|
||||
@ -3,6 +3,7 @@ package org.dromara.milvus.plus.converter;
|
||||
import io.milvus.v2.service.vector.response.GetResp;
|
||||
import io.milvus.v2.service.vector.response.QueryResp;
|
||||
import io.milvus.v2.service.vector.response.SearchResp;
|
||||
import org.apache.commons.collections4.CollectionUtils;
|
||||
import org.dromara.milvus.plus.cache.ConversionCache;
|
||||
import org.dromara.milvus.plus.cache.MilvusCache;
|
||||
import org.dromara.milvus.plus.cache.PropertyCache;
|
||||
@ -27,7 +28,7 @@ public class SearchRespConverter {
|
||||
* @param entityType 指定的Java实体类类型,用于将搜索结果的每个实体转换为该类型。
|
||||
* @return 转换后的MilvusResp对象,其中包含了列表形式的搜索结果以及操作是否成功的标志。
|
||||
*/
|
||||
public static <T> MilvusResp<List<MilvusResult<T>>> convertSearchRespToMilvusResp(SearchResp searchResp, Class<T> entityType) {
|
||||
public static <T> MilvusResp<List<MilvusResult<T>>> convertSearchRespToMilvusResp(SearchResp searchResp, Class<T> entityType, List<String> outputMetaFields) {
|
||||
// 从缓存中获取对应实体类型的转换缓存和属性缓存
|
||||
ConversionCache conversionCache = MilvusCache.milvusCache.get(entityType.getName());
|
||||
PropertyCache propertyCache = conversionCache.getPropertyCache();
|
||||
@ -41,7 +42,18 @@ public class SearchRespConverter {
|
||||
Map<String, Object> entityMap = new HashMap<>();
|
||||
for (Map.Entry<String, Object> entry : searchResult.getEntity().entrySet()) {
|
||||
String key = propertyCache.findKeyByValue(entry.getKey());
|
||||
if(key!=null){
|
||||
if (conversionCache.getMilvusEntity().getEnableDynamicField()
|
||||
&& "$meta".equals(entry.getKey())
|
||||
&& CollectionUtils.isNotEmpty(outputMetaFields)) {
|
||||
if (entry.getValue() == null) {
|
||||
continue;
|
||||
}
|
||||
Map<String, Object> 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);
|
||||
}
|
||||
@ -69,10 +81,10 @@ public class SearchRespConverter {
|
||||
* @param entityType 实体类型,用于泛型结果的类型转换。
|
||||
* @return 返回一个包含Milvus结果列表的MilvusResp对象。
|
||||
*/
|
||||
public static <T> MilvusResp<List<MilvusResult<T>>> convertGetRespToMilvusResp(QueryResp getResp, Class<T> entityType) {
|
||||
public static <T> MilvusResp<List<MilvusResult<T>>> convertGetRespToMilvusResp(QueryResp getResp, Class<T> entityType, List<String> outputMetaFields) {
|
||||
// 从QueryResp中提取查询结果
|
||||
List<QueryResp.QueryResult> queryResults = getResp.getQueryResults();
|
||||
return convertQuery(queryResults, entityType);
|
||||
return convertQuery(queryResults, entityType, outputMetaFields);
|
||||
}
|
||||
public static MilvusResp<Long> convertGetRespToCount(QueryResp getResp) {
|
||||
// 从QueryResp中提取查询结果
|
||||
@ -86,10 +98,10 @@ public class SearchRespConverter {
|
||||
* @param entityType 实体类型,用于泛型结果的类型转换。
|
||||
* @return 返回一个包含Milvus结果列表的MilvusResp对象。
|
||||
*/
|
||||
public static <T> MilvusResp<List<MilvusResult<T>>> convertGetRespToMilvusResp(GetResp getResp, Class<T> entityType) {
|
||||
public static <T> MilvusResp<List<MilvusResult<T>>> convertGetRespToMilvusResp(GetResp getResp, Class<T> entityType, List<String> outputMetaFields) {
|
||||
// 从GetResp中提取结果
|
||||
List<QueryResp.QueryResult> getResults = getResp.getResults;
|
||||
return convertQuery(getResults, entityType);
|
||||
return convertQuery(getResults, entityType, outputMetaFields);
|
||||
}
|
||||
|
||||
|
||||
@ -100,7 +112,7 @@ public class SearchRespConverter {
|
||||
* @param entityType 需要转换成的实体类型,指定了转换的目标。
|
||||
* @return MilvusResp对象,包含转换后的实体列表。每个实体都包装在一个MilvusResult对象中,同时设置成功状态为true。
|
||||
*/
|
||||
private static <T> MilvusResp<List<MilvusResult<T>>> convertQuery(List<QueryResp.QueryResult> getResults, Class<T> entityType){
|
||||
private static <T> MilvusResp<List<MilvusResult<T>>> convertQuery(List<QueryResp.QueryResult> getResults, Class<T> entityType, List<String> outputMetaFields){
|
||||
// 初始化转换缓存和属性缓存,用于帮助将查询结果映射到Java实体
|
||||
ConversionCache conversionCache = MilvusCache.milvusCache.get(entityType.getName());
|
||||
PropertyCache propertyCache = conversionCache.getPropertyCache();
|
||||
@ -113,7 +125,12 @@ public class SearchRespConverter {
|
||||
// 通过属性缓存转换键名,以适应Java实体的字段命名
|
||||
for (Map.Entry<String, Object> entry : entityMap.entrySet()) {
|
||||
String key = propertyCache.findKeyByValue(entry.getKey());
|
||||
if(key!=null){
|
||||
if (conversionCache.getMilvusEntity().getEnableDynamicField()
|
||||
&& propertyCache.metaFunctionSet.contains(entry.getKey())
|
||||
&& CollectionUtils.isNotEmpty(outputMetaFields)
|
||||
&& outputMetaFields.contains(entry.getKey())) {
|
||||
entityMap2.put(String.valueOf(entry.getKey()), entry.getValue());
|
||||
} else if(key!=null){
|
||||
Object value = entry.getValue();
|
||||
entityMap2.put(key,value);
|
||||
}
|
||||
|
||||
@ -36,6 +36,7 @@ import java.util.stream.Collectors;
|
||||
public class LambdaQueryWrapper<T> extends AbstractChainWrapper<T> implements Wrapper<LambdaQueryWrapper<T>, T> {
|
||||
private ConversionCache conversionCache;
|
||||
private List<String> outputFields;
|
||||
private List<String> outputMetaFields;
|
||||
private Class<T> entityType;
|
||||
private String collectionName;
|
||||
private String collectionAlias;
|
||||
@ -858,6 +859,9 @@ public class LambdaQueryWrapper<T> extends AbstractChainWrapper<T> implements Wr
|
||||
Collection<String> values = conversionCache.getPropertyCache().functionToPropertyMap.values();
|
||||
builder.outputFields(new ArrayList<>(values));
|
||||
}
|
||||
if (CollectionUtils.isEmpty(outputMetaFields) && !CollectionUtils.isEmpty(conversionCache.getPropertyCache().metaFunctionSet)) {
|
||||
outputMetaFields = new ArrayList<>(conversionCache.getPropertyCache().metaFunctionSet);
|
||||
}
|
||||
if (!searchParams.isEmpty()) {
|
||||
builder.searchParams(searchParams);
|
||||
}
|
||||
@ -914,6 +918,9 @@ public class LambdaQueryWrapper<T> extends AbstractChainWrapper<T> implements Wr
|
||||
Collection<String> values = conversionCache.getPropertyCache().functionToPropertyMap.values();
|
||||
builder.outputFields(new ArrayList<>(values));
|
||||
}
|
||||
if (CollectionUtils.isEmpty(outputMetaFields) && !CollectionUtils.isEmpty(conversionCache.getPropertyCache().metaFunctionSet)) {
|
||||
outputMetaFields = new ArrayList<>(conversionCache.getPropertyCache().metaFunctionSet);
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
private HybridSearchReq buildHybrid(){
|
||||
@ -955,6 +962,9 @@ public class LambdaQueryWrapper<T> extends AbstractChainWrapper<T> implements Wr
|
||||
Collection<String> values = conversionCache.getPropertyCache().functionToPropertyMap.values();
|
||||
reqBuilder.outFields(new ArrayList<>(values));
|
||||
}
|
||||
if (CollectionUtils.isEmpty(outputMetaFields) && !CollectionUtils.isEmpty(conversionCache.getPropertyCache().metaFunctionSet)) {
|
||||
outputMetaFields = new ArrayList<>(conversionCache.getPropertyCache().metaFunctionSet);
|
||||
}
|
||||
if (!CollectionUtils.isEmpty(partitionNames)) {
|
||||
reqBuilder.partitionNames(partitionNames);
|
||||
}
|
||||
@ -977,18 +987,18 @@ public class LambdaQueryWrapper<T> extends AbstractChainWrapper<T> 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 +1012,15 @@ public class LambdaQueryWrapper<T> extends AbstractChainWrapper<T> implements Wr
|
||||
public MilvusResp<List<MilvusResult<T>>> query(FieldFunction<T, ?>... outputFields) throws MilvusException {
|
||||
List<String> otf = new ArrayList<>();
|
||||
for (FieldFunction<T, ?> 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 +1045,19 @@ public class LambdaQueryWrapper<T> extends AbstractChainWrapper<T> implements Wr
|
||||
}
|
||||
|
||||
public MilvusResp<List<MilvusResult<T>>> 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 +1071,7 @@ public class LambdaQueryWrapper<T> extends AbstractChainWrapper<T> implements Wr
|
||||
GetReq getReq = builder.build();
|
||||
GetResp getResp = client.get(getReq);
|
||||
|
||||
return SearchRespConverter.convertGetRespToMilvusResp(getResp, entityType);
|
||||
return SearchRespConverter.convertGetRespToMilvusResp(getResp, entityType, outputMetaFields);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user