diff --git a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/cache/CollectionToPrimaryCache.java b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/cache/CollectionToPrimaryCache.java new file mode 100644 index 0000000..d337d92 --- /dev/null +++ b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/cache/CollectionToPrimaryCache.java @@ -0,0 +1,12 @@ +package io.github.javpower.milvus.plus.cache; + +import java.util.HashMap; +import java.util.Map; +/** + * @author xgc + **/ +public class CollectionToPrimaryCache { + + public Map collectionToPrimary = new HashMap<>();//集合名称->主键名称 + +} diff --git a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/cache/ConversionCache.java b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/cache/ConversionCache.java index cbc2722..9c11c5b 100644 --- a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/cache/ConversionCache.java +++ b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/cache/ConversionCache.java @@ -8,7 +8,7 @@ import lombok.Data; @Data public class ConversionCache { private String collectionName; - private FieldFunctionCache fieldFunctionCache; + private CollectionToPrimaryCache collectionToPrimaryCache; private PropertyCache propertyCache; private MilvusEntity milvusEntity; diff --git a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/cache/FieldFunctionCache.java b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/cache/FieldFunctionCache.java deleted file mode 100644 index af5bc15..0000000 --- a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/cache/FieldFunctionCache.java +++ /dev/null @@ -1,44 +0,0 @@ -package io.github.javpower.milvus.plus.cache; - -import io.github.javpower.milvus.plus.core.FieldFunction; - -import java.lang.reflect.Field; -import java.lang.reflect.Method; -import java.util.HashMap; -import java.util.Map; -/** - * @author xgc - **/ -public class FieldFunctionCache { - - public Map> propertyToFunctionMap = new HashMap<>();//属性名称获取对应的函数 - - public String getMethodName(Field field,String fieldName){ - String capitalizedFieldName = fieldName.substring(0, 1).toUpperCase() + fieldName.substring(1); - String getMethodName = "get" + capitalizedFieldName; // 构建get方法名称 - - // 检查字段类型是否为boolean,如果是,get方法名称应以is开头 - if (field.getType() == boolean.class) { - getMethodName = "is" + capitalizedFieldName; - } - return getMethodName; - } - public String getFieldName(FieldFunction fieldFunction) { - for (Map.Entry> entry : propertyToFunctionMap.entrySet()) { - if (entry.getValue().equals(fieldFunction)) { - return entry.getKey(); // 返回匹配的属性名称 - } - } - return null; // 如果没有找到匹配项,返回null - } - public FieldFunction createFunction(Method method) { - return (instance) -> { - try { - return method.invoke(instance); - } catch (Exception e) { - // 异常处理 - return null; - } - }; - } -} diff --git a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/converter/MilvusEntityConverter.java b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/converter/MilvusEntityConverter.java index a901c17..45cf008 100644 --- a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/converter/MilvusEntityConverter.java +++ b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/converter/MilvusEntityConverter.java @@ -5,17 +5,15 @@ import io.github.javpower.milvus.plus.annotation.MilvusCollection; import io.github.javpower.milvus.plus.annotation.MilvusField; import io.github.javpower.milvus.plus.annotation.MilvusIndex; import io.github.javpower.milvus.plus.cache.ConversionCache; -import io.github.javpower.milvus.plus.cache.FieldFunctionCache; +import io.github.javpower.milvus.plus.cache.CollectionToPrimaryCache; import io.github.javpower.milvus.plus.cache.MilvusCache; import io.github.javpower.milvus.plus.cache.PropertyCache; -import io.github.javpower.milvus.plus.core.FieldFunction; import io.github.javpower.milvus.plus.model.MilvusEntity; import io.milvus.v2.common.IndexParam; import io.milvus.v2.service.collection.request.AddFieldReq; import org.apache.commons.lang3.StringUtils; import java.lang.reflect.Field; -import java.lang.reflect.Method; import java.util.ArrayList; import java.util.List; /** @@ -34,19 +32,14 @@ public class MilvusEntityConverter { List milvusFields = new ArrayList<>(); List indexParams=new ArrayList<>(); PropertyCache propertyCache=new PropertyCache(); - FieldFunctionCache fieldFunctionCache=new FieldFunctionCache(); + CollectionToPrimaryCache collectionToPrimaryCache =new CollectionToPrimaryCache(); 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); - String methodName = fieldFunctionCache.getMethodName(field, field.getName()); - try { - Method method = entityClass.getMethod(methodName); - FieldFunction function = fieldFunctionCache.createFunction(method); - fieldFunctionCache.propertyToFunctionMap.put(field.getName(),function); - } catch (NoSuchMethodException e) { - throw new RuntimeException(e); + if (fieldAnnotation.isPrimaryKey()) { + collectionToPrimaryCache.collectionToPrimary.put(collectionName,fieldName); } AddFieldReq milvusField = AddFieldReq.builder() .fieldName(fieldName) @@ -75,7 +68,7 @@ public class MilvusEntityConverter { conversionCache.setMilvusEntity(milvus); conversionCache.setCollectionName(collectionName); conversionCache.setPropertyCache(propertyCache); - conversionCache.setFieldFunctionCache(fieldFunctionCache); + conversionCache.setCollectionToPrimaryCache(collectionToPrimaryCache); MilvusCache.milvusCache.put(entityClass,conversionCache); return milvus; } diff --git a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/converter/SearchRespConverter.java b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/converter/SearchRespConverter.java index fc8ce13..5df87de 100644 --- a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/converter/SearchRespConverter.java +++ b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/converter/SearchRespConverter.java @@ -1,14 +1,18 @@ package io.github.javpower.milvus.plus.converter; -import com.fasterxml.jackson.core.JsonProcessingException; -import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import io.github.javpower.milvus.plus.model.vo.MilvusResp; import io.github.javpower.milvus.plus.model.vo.MilvusResult; import io.github.javpower.milvus.plus.model.vo.MilvusResultVo; +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 java.util.ArrayList; import java.util.List; +import java.util.Map; +import java.util.stream.Collectors; + /** * @author xgc **/ @@ -16,26 +20,55 @@ public class SearchRespConverter { private static final ObjectMapper objectMapper = new ObjectMapper(); - public static MilvusResp> convertSearchRespToMilvusResp(SearchResp searchResp, Class entityType){ + public static MilvusResp> convertSearchRespToMilvusResp(SearchResp searchResp, Class entityType) { List> searchResults = searchResp.getSearchResults(); + // 将searchResults中的每个SearchResult转换为MilvusResult + List>> milvusResults = searchResults.stream() + .map(innerList -> innerList.stream() + .map(searchResult -> { + try { + // 使用ObjectMapper将Map转换为Java实体类T + T entity = objectMapper.convertValue(searchResult.getEntity(), entityType); + MilvusResult 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()); - // 反序列化JSON字符串到具体的MilvusResult对象列表 - TypeReference>>> typeRef = new TypeReference>>>() {}; - List>> milvusResults = null; - try { - // 将searchResults转换为JSON字符串 - String jsonResults = objectMapper.writeValueAsString(searchResults); - milvusResults = objectMapper.readValue(jsonResults, typeRef); - } catch (JsonProcessingException e) { - throw new RuntimeException(e); - } - // 创建MilvusResp对象并设置结果 - MilvusResp> milvusResp = new MilvusResp<>(); - MilvusResultVo vo=new MilvusResultVo<>(); + // 创建MilvusResultVo对象并设置结果 + MilvusResultVo vo = new MilvusResultVo<>(); vo.setVo(milvusResults); + // 创建MilvusResp对象并设置结果和成功标志 + MilvusResp> milvusResp = new MilvusResp<>(); milvusResp.setData(vo); milvusResp.setSuccess(true); + return milvusResp; } + public static MilvusResp> convertGetRespToMilvusResp(GetResp getResp, Class entityType) { + // 解析GetResp中的查询结果 + List getResults = getResp.getResults; + List entities = new ArrayList<>(); + // 遍历每个查询结果,并将它们映射到Java实体类T的实例 + for (QueryResp.QueryResult queryResult : getResults) { + Map entityMap = queryResult.getEntity(); + // 假设有一个方法可以从Map映射到实体类T,这个方法需要自定义实现 + T entity = objectMapper.convertValue(entityMap, entityType); + entities.add(entity); + } + // 创建MilvusResp对象,并将实体列表作为其数据部分 + MilvusResp> milvusResp = new MilvusResp<>(); + milvusResp.setData(entities); + milvusResp.setSuccess(true); + // 返回MilvusResp对象 + return milvusResp; + } } \ No newline at end of file diff --git a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/core/conditions/LambdaDeleteWrapper.java b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/core/conditions/LambdaDeleteWrapper.java index 67f8d43..050bcdd 100644 --- a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/core/conditions/LambdaDeleteWrapper.java +++ b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/core/conditions/LambdaDeleteWrapper.java @@ -11,6 +11,7 @@ import io.milvus.v2.service.vector.response.DeleteResp; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.util.ArrayList; import java.util.Arrays; import java.util.List; @@ -358,6 +359,10 @@ public class LambdaDeleteWrapper extends AbstractChainWrapper implements resp.setSuccess(true); return resp; } + public MilvusResp removeById(Serializable ... ids) throws MilvusException { + this.id(ids); + return remove(); + } @Override public void init(String collectionName, MilvusClient client, ConversionCache conversionCache, Class entityType) { diff --git a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/core/conditions/LambdaSearchWrapper.java b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/core/conditions/LambdaSearchWrapper.java index e7989bb..e84840e 100644 --- a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/core/conditions/LambdaSearchWrapper.java +++ b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/core/conditions/LambdaSearchWrapper.java @@ -9,12 +9,16 @@ import io.github.javpower.milvus.plus.model.vo.MilvusResultVo; import io.github.javpower.milvus.plus.service.MilvusClient; import io.milvus.exception.MilvusException; import io.milvus.v2.common.ConsistencyLevel; +import io.milvus.v2.service.vector.request.GetReq; import io.milvus.v2.service.vector.request.SearchReq; +import io.milvus.v2.service.vector.response.GetResp; import io.milvus.v2.service.vector.response.SearchResp; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import java.io.Serializable; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; /** @@ -345,8 +349,8 @@ public class LambdaSearchWrapper extends AbstractChainWrapper implements private SearchReq build() { SearchReq.SearchReqBuilder builder = SearchReq.builder() .collectionName(collectionName) - .annsField(annsField) - .topK(topK); + .annsField(annsField); + if (!vectors.isEmpty()) { builder.data(vectors); } @@ -354,6 +358,9 @@ public class LambdaSearchWrapper extends AbstractChainWrapper implements if (filterStr != null && !filterStr.isEmpty()) { builder.filter(filterStr); } + if(topK>0){ + builder.topK(topK); + } if(limit>0){ builder.limit(limit); } @@ -372,6 +379,17 @@ public class LambdaSearchWrapper extends AbstractChainWrapper implements MilvusResp> tMilvusResp = SearchRespConverter.convertSearchRespToMilvusResp(search, entityType); return tMilvusResp; } + public MilvusResp> getById(Serializable ... ids){ + GetReq getReq = GetReq.builder() + .collectionName(collectionName) + .ids(Arrays.asList(ids)) + .build(); + GetResp getResp = client.client.get(getReq); + MilvusResp> tMilvusResp = SearchRespConverter.convertGetRespToMilvusResp(getResp, entityType); + return tMilvusResp; + + } + @Override public void init(String collectionName, MilvusClient client, ConversionCache conversionCache, Class entityType) { setClient(client); diff --git a/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/core/conditions/LambdaUpdateWrapper.java b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/core/conditions/LambdaUpdateWrapper.java new file mode 100644 index 0000000..142f785 --- /dev/null +++ b/milvus-plus-boot-starter/src/main/java/io/github/javpower/milvus/plus/core/conditions/LambdaUpdateWrapper.java @@ -0,0 +1,449 @@ +package io.github.javpower.milvus.plus.core.conditions; + +import com.alibaba.fastjson.JSON; +import com.alibaba.fastjson.JSONObject; +import io.github.javpower.milvus.plus.cache.CollectionToPrimaryCache; +import io.github.javpower.milvus.plus.cache.ConversionCache; +import io.github.javpower.milvus.plus.cache.PropertyCache; +import io.github.javpower.milvus.plus.core.FieldFunction; +import io.github.javpower.milvus.plus.model.vo.MilvusResp; +import io.github.javpower.milvus.plus.service.MilvusClient; +import io.milvus.exception.MilvusException; +import io.milvus.v2.service.vector.request.SearchReq; +import io.milvus.v2.service.vector.request.UpsertReq; +import io.milvus.v2.service.vector.response.SearchResp; +import io.milvus.v2.service.vector.response.UpsertResp; +import lombok.Data; +import lombok.extern.slf4j.Slf4j; + +import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; + +/** + * 搜索构建器内部类,用于构建搜索请求 + */ +@Data +@Slf4j +public class LambdaUpdateWrapper extends AbstractChainWrapper implements Wrapper,T>{ + private ConversionCache conversionCache; + private Class entityType; + private String collectionName; + private MilvusClient client; + + public LambdaUpdateWrapper(String collectionName, MilvusClient client, ConversionCache conversionCache, Class entityType) { + this.collectionName = collectionName; + this.client = client; + this.conversionCache=conversionCache; + this.entityType=entityType; + } + + public LambdaUpdateWrapper() { + + } + /** + * 添加等于条件。 + * + * @param fieldName 字段名 + * @param value 要比较的值 + * @return 当前条件构建器对象 + */ + protected LambdaUpdateWrapper eq(String fieldName, Object value) { + super.eq(fieldName,value); + return this; + } + + /** + * 添加不等于条件。 + * + * @param fieldName 字段名 + * @param value 要比较的值 + * @return 当前条件构建器对象 + */ + protected LambdaUpdateWrapper ne(String fieldName, Object value) { + super.ne(fieldName,value); + return this; + } + + /** + * 添加大于条件。 + * + * @param fieldName 字段名 + * @param value 要比较的值 + * @return 当前条件构建器对象 + */ + protected LambdaUpdateWrapper gt(String fieldName, Object value) { + super.gt(fieldName,value); + return this; + } + + /** + * 添加大于等于条件。 + * + * @param fieldName 字段名 + * @param value 要比较的值 + * @return 当前条件构建器对象 + */ + protected LambdaUpdateWrapper ge(String fieldName, Object value) { + super.ge(fieldName,value); + return this; + } + + /** + * 添加小于条件。 + * + * @param fieldName 字段名 + * @param value 要比较的值 + * @return 当前条件构建器对象 + */ + protected LambdaUpdateWrapper lt(String fieldName, Object value) { + super.lt(fieldName,value); + return this; + } + + /** + * 添加小于等于条件。 + * + * @param fieldName 字段名 + * @param value 要比较的值 + * @return 当前条件构建器对象 + */ + protected LambdaUpdateWrapper le(String fieldName, Object value) { + super.le(fieldName,value); + return this; + } + + /** + * 添加范围条件。 + * + * @param fieldName 字段名 + * @param start 范围开始值 + * @param end 范围结束值 + * @return 当前条件构建器对象 + */ + protected LambdaUpdateWrapper between(String fieldName, Object start, Object end) { + super.between(fieldName,start,end); + return this; + } + + /** + * 添加空值检查条件。 + * + * @param fieldName 字段名 + * @return 当前条件构建器对象 + */ + protected LambdaUpdateWrapper isNull(String fieldName) { + super.isNull(fieldName); + return this; + } + + /** + * 添加非空值检查条件。 + * + * @param fieldName 字段名 + * @return 当前条件构建器对象 + */ + protected LambdaUpdateWrapper isNotNull(String fieldName) { + super.isNotNull(fieldName); + return this; + } + + /** + * 添加IN条件。 + * + * @param fieldName 字段名 + * @param values 要检查的值列表 + * @return 当前条件构建器对象 + */ + protected LambdaUpdateWrapper in(String fieldName, List values) { + super.in(fieldName,values); + return this; + } + + /** + * 添加LIKE条件。 + * + * @param fieldName 字段名 + * @param value 要匹配的模式 + * @return 当前条件构建器对象 + */ + protected LambdaUpdateWrapper like(String fieldName, String value) { + super.like(fieldName,value); + return this; + } + + public LambdaUpdateWrapper jsonContains(String fieldName, Object value) { + super.jsonContains(fieldName,value); + return this; + } + + public LambdaUpdateWrapper jsonContainsAll(String fieldName, List values) { + super.jsonContainsAll(fieldName,values); + return this; + } + + public LambdaUpdateWrapper jsonContainsAny(String fieldName, List values) { + super.jsonContainsAny(fieldName,values); + return this; + } + + // Array operations + public LambdaUpdateWrapper arrayContains(String fieldName, Object value) { + super.arrayContains(fieldName,value); + return this; + } + + public LambdaUpdateWrapper arrayContainsAll(String fieldName, List values) { + super.arrayContainsAll(fieldName,values); + return this; + } + + public LambdaUpdateWrapper arrayContainsAny(String fieldName, List values) { + super.arrayContainsAny(fieldName,values); + return this; + } + + public LambdaUpdateWrapper arrayLength(String fieldName, int length) { + super.arrayLength(fieldName,length); + return this; + } + + public LambdaUpdateWrapper eq(FieldFunction fieldName, Object value) { + super.eq(fieldName,value); + return this; + } + + public LambdaUpdateWrapper ne(FieldFunction fieldName, Object value) { + super.ne(fieldName,value); + return this; + } + + public LambdaUpdateWrapper gt(FieldFunction fieldName, Object value) { + super.gt(fieldName,value); + return this; + } + + public LambdaUpdateWrapper ge(FieldFunction fieldName, Object value) { + super.ge(fieldName,value); + return this; + } + + public LambdaUpdateWrapper lt(FieldFunction fieldName, Object value) { + super.lt(fieldName,value); + return this; + } + + public LambdaUpdateWrapper le(FieldFunction fieldName, Object value) { + super.le(fieldName,value); + return this; + } + + // Range operation + public LambdaUpdateWrapper between(FieldFunction fieldName, Object start, Object end) { + super.between(fieldName,start,end); + return this; + } + + // Null check + public LambdaUpdateWrapper isNull(FieldFunction fieldName) { + super.isNull(fieldName); + return this; + } + + public LambdaUpdateWrapper isNotNull(FieldFunction fieldName) { + super.isNotNull(fieldName); + return this; + } + + // In operator + public LambdaUpdateWrapper in(FieldFunction fieldName, List values) { + super.in(fieldName,values); + return this; + } + + // Like operator + public LambdaUpdateWrapper like(FieldFunction fieldName, String value) { + super.like(fieldName,value); + return this; + } + + // JSON array operations + public LambdaUpdateWrapper jsonContains(FieldFunction fieldName, Object value) { + super.jsonContains(fieldName,value); + return this; + } + + public LambdaUpdateWrapper jsonContainsAll(FieldFunction fieldName, List values) { + super.jsonContainsAll(fieldName,values); + return this; + } + + public LambdaUpdateWrapper jsonContainsAny(FieldFunction fieldName, List values) { + super.jsonContainsAny(fieldName,values); + return this; + } + + // Array operations + public LambdaUpdateWrapper arrayContains(FieldFunction fieldName, Object value) { + super.arrayContains(fieldName,value); + return this; + } + + public LambdaUpdateWrapper arrayContainsAll(FieldFunction fieldName, List values) { + super.arrayContainsAll(fieldName,values); + return this; + } + public LambdaUpdateWrapper arrayContainsAny(FieldFunction fieldName, List values) { + super.arrayContainsAny(fieldName,values); + return this; + } + + public LambdaUpdateWrapper arrayLength(FieldFunction fieldName, int length) { + super.arrayLength(fieldName,length); + return this; + } + + // Logic operations + public LambdaUpdateWrapper and(ConditionBuilder other) { + super.and(other); + return this; + } + + public LambdaUpdateWrapper or(ConditionBuilder other) { + super.or(other); + return this; + } + + public LambdaUpdateWrapper not() { + super.not(); + return this; + } + /** + * 构建完整的删除请求 + * @return 搜索请求对象 + */ + private SearchResp build() { + String filterStr = buildFilters(); + if (filterStr != null && !filterStr.isEmpty()) { + SearchReq.SearchReqBuilder builder = SearchReq.builder() + .collectionName(collectionName).filter(filterStr); + SearchResp search = client.client.search(builder.build()); + return search; + }else { + return null; + } + } + + /** + * 执行更新 + * @return 更新响应对象 + */ + public MilvusResp update(T t) throws MilvusException { + List jsonObjects=new ArrayList<>(); + SearchResp searchResp = build(); + List ids=new ArrayList<>(); + if(searchResp!=null){ + for (List searchResult : searchResp.getSearchResults()) { + for (SearchResp.SearchResult result : searchResult) { + ids.add(result.getId()); + } + } + } + Map propertiesMap = getPropertiesMap(t); + PropertyCache propertyCache = conversionCache.getPropertyCache(); + CollectionToPrimaryCache collectionToPrimaryCache = conversionCache.getCollectionToPrimaryCache(); + String pk = collectionToPrimaryCache.collectionToPrimary.get(collectionName); + Boolean havePk=false; + JSONObject jsonObject=new JSONObject(); + for (Map.Entry entry : propertiesMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + String tk = propertyCache.functionToPropertyMap.get(key); + if(pk.equals(tk)){ + havePk=true; + } + jsonObject.put(tk,value); + } + if(!havePk&&ids.size()==0){ + throw new MilvusException("not find primary key",400); + } + if(havePk){ + jsonObjects.add(jsonObject); + }else { + for (Object id : ids) { + jsonObject.put(pk,id); + jsonObjects.add(jsonObject); + } + } + return update(jsonObjects); + } + private MilvusResp update(List jsonObjects){ + log.info("update data--->{}", JSON.toJSONString(jsonObjects)); + UpsertReq upsertReq = UpsertReq.builder() + .collectionName(collectionName) + .data(jsonObjects) + .build(); + UpsertResp upsert = client.client.upsert(upsertReq); + MilvusResp resp=new MilvusResp(); + resp.setData(upsert); + resp.setSuccess(true); + return resp; + } + + public MilvusResp updateById(T ...t) throws MilvusException { + PropertyCache propertyCache = conversionCache.getPropertyCache(); + CollectionToPrimaryCache collectionToPrimaryCache = conversionCache.getCollectionToPrimaryCache(); + String pk = collectionToPrimaryCache.collectionToPrimary.get(collectionName); + List jsonObjects=new ArrayList<>(); + for (T t1 : t) { + Map propertiesMap = getPropertiesMap(t1); + JSONObject jsonObject=new JSONObject(); + for (Map.Entry entry : propertiesMap.entrySet()) { + String key = entry.getKey(); + Object value = entry.getValue(); + String tk = propertyCache.functionToPropertyMap.get(key); + jsonObject.put(tk,value); + } + if (!jsonObject.containsKey(pk)) { + throw new MilvusException("not find primary key",400); + } + jsonObjects.add(jsonObject); + + } + return update(jsonObjects); + } + private Map getPropertiesMap(T t) { + Map propertiesMap = new HashMap<>(); + Class clazz = t.getClass(); + Field[] fields = clazz.getDeclaredFields(); // 获取所有属性 + for (Field field : fields) { + try { + field.setAccessible(true); // 确保私有属性也可以访问 + String fieldName = field.getName(); // 获取属性名 + Object value = field.get(t); // 获取属性值 + if(value!=null){ + propertiesMap.put(fieldName, value); // 将属性名和属性值放入Map + } + } catch (IllegalAccessException e) { + // 异常处理,实际开发中可以根据需要记录日志或进行其他处理 + throw new RuntimeException("Error accessing field", e); + } + } + return propertiesMap; // 返回包含属性名和属性值的Map + } + + @Override + public void init(String collectionName, MilvusClient client, ConversionCache conversionCache, Class entityType) { + setClient(client); + setCollectionName(collectionName); + setEntityType(entityType); + setConversionCache(conversionCache); + } + + @Override + public LambdaUpdateWrapper wrapper() { + return this; + } +} \ No newline at end of file