初始化扫描指定包实体类缓存+自动构建集合

This commit is contained in:
xgc 2024-05-12 02:38:25 +08:00
parent f601a1947e
commit c8abc65a51
17 changed files with 241 additions and 181 deletions

View File

@ -2,6 +2,9 @@ package io.github.javpower.milvus.demo;
import org.springframework.boot.SpringApplication; import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationPropertiesScan;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.stereotype.Component;
@SpringBootApplication @SpringBootApplication
public class MilvusDemoApplication { public class MilvusDemoApplication {

View File

@ -1,7 +1,7 @@
package io.github.javpower.milvus.plus.builder; package io.github.javpower.milvus.plus.builder;
import io.github.javpower.milvus.plus.service.MilvusClient;
import io.milvus.exception.MilvusException; import io.milvus.exception.MilvusException;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.IndexParam; import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.AddFieldReq; import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.CreateCollectionReq; import io.milvus.v2.service.collection.request.CreateCollectionReq;
@ -12,13 +12,13 @@ import io.milvus.v2.service.index.request.CreateIndexReq;
public class CollectionSchemaBuilder { public class CollectionSchemaBuilder {
private final String collectionName; private final String collectionName;
private final MilvusClient wrapper; private final MilvusClientV2 wrapper;
private final CreateCollectionReq.CollectionSchema schema; private final CreateCollectionReq.CollectionSchema schema;
public CollectionSchemaBuilder(String collectionName, MilvusClient wrapper) { public CollectionSchemaBuilder(String collectionName, MilvusClientV2 wrapper) {
this.collectionName = collectionName; this.collectionName = collectionName;
this.wrapper = wrapper; this.wrapper = wrapper;
this.schema = wrapper.client.createSchema(); this.schema = wrapper.createSchema();
} }
public CollectionSchemaBuilder addField(AddFieldReq field) { public CollectionSchemaBuilder addField(AddFieldReq field) {
@ -34,13 +34,13 @@ public class CollectionSchemaBuilder {
public void createSchema() throws MilvusException { public void createSchema() throws MilvusException {
CreateCollectionReq req=CreateCollectionReq.builder().collectionName(this.collectionName).collectionSchema(this.schema).build(); CreateCollectionReq req=CreateCollectionReq.builder().collectionName(this.collectionName).collectionSchema(this.schema).build();
wrapper.client.createCollection(req); wrapper.createCollection(req);
} }
public void createIndex(java.util.List<IndexParam> indexParams) throws MilvusException { public void createIndex(java.util.List<IndexParam> indexParams) throws MilvusException {
CreateIndexReq req = CreateIndexReq.builder() CreateIndexReq req = CreateIndexReq.builder()
.collectionName(collectionName) .collectionName(collectionName)
.indexParams(indexParams) .indexParams(indexParams)
.build(); .build();
wrapper.client.createIndex(req); wrapper.createIndex(req);
} }
} }

View File

@ -9,4 +9,14 @@ public class PropertyCache {
public Map<String, String> functionToPropertyMap = new HashMap<>(); //属性名称->表名称 public Map<String, String> functionToPropertyMap = new HashMap<>(); //属性名称->表名称
// 根据值查找第一个匹配的键
public String findKeyByValue(String value) {
for (Map.Entry<String, String> entry : functionToPropertyMap.entrySet()) {
if (value.equals(entry.getValue())) {
return entry.getKey(); // 返回与值匹配的第一个键
}
}
return null; // 如果没有找到匹配的键返回null
}
} }

View File

@ -1,40 +0,0 @@
package io.github.javpower.milvus.plus.config;
import io.github.javpower.milvus.plus.annotation.MilvusCollection;
import io.github.javpower.milvus.plus.service.MilvusCollectionService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import java.util.Arrays;
/**
* @author xgc
**/
@Component
public class MilvusCollectionConfig implements ApplicationRunner {
private final ApplicationContext applicationContext;
private final MilvusCollectionService milvusCollectionService;
@Autowired(required = false)
public MilvusCollectionConfig(ApplicationContext applicationContext, MilvusCollectionService milvusCollectionService) {
this.applicationContext = applicationContext;
this.milvusCollectionService = milvusCollectionService;
}
@Override
public void run(ApplicationArguments args) throws Exception {
// 获取所有带有@MilvusCollection注解的类
String[] beanNames = applicationContext.getBeanNamesForAnnotation(MilvusCollection.class);
Class<?>[] annotatedClasses = Arrays.stream(beanNames)
.map(applicationContext::getType)
.toArray(Class<?>[]::new);
// 调用业务处理服务
if(milvusCollectionService!=null){
milvusCollectionService.performBusinessLogic(Arrays.asList(annotatedClasses));
}
}
}

View File

@ -4,11 +4,13 @@ import io.milvus.v2.client.ConnectConfig;
import io.milvus.v2.client.MilvusClientV2; import io.milvus.v2.client.MilvusClientV2;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
/** /**
* @author xgc * @author xgc
**/ **/
@Configuration @Configuration
public class MilvusConfig { public class MilvusConfig {
private final MilvusProperties properties; private final MilvusProperties properties;
public MilvusConfig(MilvusProperties properties) { public MilvusConfig(MilvusProperties properties) {
@ -22,8 +24,9 @@ public class MilvusConfig {
} }
ConnectConfig connectConfig = ConnectConfig.builder() ConnectConfig connectConfig = ConnectConfig.builder()
.uri(properties.getUri()) .uri(properties.getUri())
.token(properties.getToken()) // .token(properties.getToken())
.build(); .build();
return new MilvusClientV2(connectConfig); return new MilvusClientV2(connectConfig);
} }
} }

View File

@ -0,0 +1,139 @@
package io.github.javpower.milvus.plus.config;
import io.github.javpower.milvus.plus.annotation.MilvusCollection;
import io.github.javpower.milvus.plus.builder.CollectionSchemaBuilder;
import io.github.javpower.milvus.plus.converter.MilvusEntityConverter;
import io.github.javpower.milvus.plus.model.MilvusEntity;
import io.milvus.exception.MilvusException;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.*;
import io.milvus.v2.service.collection.response.DescribeCollectionResp;
import lombok.extern.slf4j.Slf4j;
import org.springframework.core.io.Resource;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;
import org.springframework.core.io.support.ResourcePatternResolver;
import org.springframework.core.type.classreading.CachingMetadataReaderFactory;
import org.springframework.core.type.classreading.MetadataReader;
import org.springframework.core.type.classreading.MetadataReaderFactory;
import org.springframework.stereotype.Service;
import org.springframework.util.ClassUtils;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author xgc
**/
@Service
@Slf4j
public class MilvusInit implements AutoCloseable {
private final static String CLASS="*.class";
public final MilvusClientV2 client;
public MilvusInit(MilvusClientV2 client, MilvusProperties properties) {
this.client = client;
List<Class<?>> classes = getClass(properties.getPackages());
performBusinessLogic(classes);
}
@Override
public void close() throws InterruptedException {
client.close(10);
}
//获取指定包下实体类
private List<Class<?>> getClass(List<String> packages){
List<Class<?>> res=new ArrayList<>();
ResourcePatternResolver resourcePatternResolver = new PathMatchingResourcePatternResolver();
for (String pg : packages) {
String pattern = ResourcePatternResolver.CLASSPATH_ALL_URL_PREFIX +
ClassUtils.convertClassNameToResourcePath(pg+".") + CLASS;
try {
Resource[] resources = resourcePatternResolver.getResources(pattern);
MetadataReaderFactory readerFactory = new CachingMetadataReaderFactory(resourcePatternResolver);
for (Resource resource : resources) {
MetadataReader reader = readerFactory.getMetadataReader(resource);
String classname = reader.getClassMetadata().getClassName();
Class<?> clazz = Class.forName(classname);
MilvusCollection annotation = clazz.getAnnotation(MilvusCollection.class);
if(annotation!=null){
res.add(clazz);
}
}
}catch (Exception e){
e.printStackTrace();
}
}
return res;
}
//缓存+是否构建集合
public void performBusinessLogic(List<Class<?>> annotatedClasses) {
for (Class<?> milvusClass : annotatedClasses) {
MilvusEntity milvusEntity = MilvusEntityConverter.convert(milvusClass);
try {
String collectionName = milvusEntity.getCollectionName();
// 检查集合是否存在
boolean collectionExists = client.hasCollection(
HasCollectionReq.builder().collectionName(collectionName).build()
);
if (collectionExists) {
// 获取集合的详细信息
DescribeCollectionResp collectionInfo = client.describeCollection(
DescribeCollectionReq.builder().collectionName(collectionName).build()
);
// 检查字段是否一致这里需要实现字段比较逻辑
List<String> existingFieldNames = collectionInfo.getFieldNames();
List<AddFieldReq> requiredFields = milvusEntity.getMilvusFields();
List<String> requiredFieldNames = requiredFields.stream().map(AddFieldReq::getFieldName).collect(Collectors.toList());
if (!new HashSet<>(existingFieldNames).containsAll(requiredFieldNames) || !new HashSet<>(requiredFieldNames).containsAll(existingFieldNames)) {
// 字段不一致删除并重新创建集合
client.dropCollection(
DropCollectionReq.builder().collectionName(collectionName).build()
);
// 创建新集合
create(milvusEntity,client);
loadStatus(collectionName);
}
} else {
// 创建新集合
create(milvusEntity,client);
loadStatus(collectionName);
}
} catch (MilvusException e) {
throw new RuntimeException("Error handling Milvus collection", e);
}
}
}
private void create(MilvusEntity milvusEntity,MilvusClientV2 client){
// 创建新集合
CollectionSchemaBuilder schemaBuilder = new CollectionSchemaBuilder(
milvusEntity.getCollectionName(), client
);
schemaBuilder.addField(milvusEntity.getMilvusFields().toArray(new AddFieldReq[0]));
List<IndexParam> indexParams = milvusEntity.getIndexParams();
log.info("-------create schema---------");
schemaBuilder.createSchema();
if (indexParams != null && !indexParams.isEmpty()) {
schemaBuilder.createIndex(indexParams);
log.info("-------create index---------");
}
}
private void loadStatus(String collectionName){
GetLoadStateReq getLoadStateReq = GetLoadStateReq.builder()
.collectionName(collectionName)
.build();
Boolean resp = client.getLoadState(getLoadStateReq);
log.info("LoadState-->{}", resp);
if(!resp){
LoadCollectionReq loadCollectionReq = LoadCollectionReq.builder()
.collectionName(collectionName)
.build();
client.loadCollection(loadCollectionReq);
}
}
}

View File

@ -3,6 +3,9 @@ package io.github.javpower.milvus.plus.config;
import lombok.Data; import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component; import org.springframework.stereotype.Component;
import java.util.List;
/** /**
* @author xgc * @author xgc
**/ **/
@ -13,4 +16,5 @@ public class MilvusProperties {
private boolean enable; private boolean enable;
private String uri; private String uri;
private String token; private String token;
private List<String> packages;
} }

View File

@ -1,11 +1,12 @@
package io.github.javpower.milvus.plus.converter; package io.github.javpower.milvus.plus.converter;
import io.github.javpower.milvus.plus.annotation.ExtraParam;
import io.github.javpower.milvus.plus.annotation.MilvusCollection; import io.github.javpower.milvus.plus.annotation.MilvusCollection;
import io.github.javpower.milvus.plus.annotation.MilvusField; import io.github.javpower.milvus.plus.annotation.MilvusField;
import io.github.javpower.milvus.plus.annotation.MilvusIndex; import io.github.javpower.milvus.plus.annotation.MilvusIndex;
import io.github.javpower.milvus.plus.cache.ConversionCache;
import io.github.javpower.milvus.plus.cache.CollectionToPrimaryCache; import io.github.javpower.milvus.plus.cache.CollectionToPrimaryCache;
import io.github.javpower.milvus.plus.cache.ConversionCache;
import io.github.javpower.milvus.plus.cache.MilvusCache; import io.github.javpower.milvus.plus.cache.MilvusCache;
import io.github.javpower.milvus.plus.cache.PropertyCache; import io.github.javpower.milvus.plus.cache.PropertyCache;
import io.github.javpower.milvus.plus.model.MilvusEntity; import io.github.javpower.milvus.plus.model.MilvusEntity;
@ -15,7 +16,10 @@ import org.apache.commons.lang3.StringUtils;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map;
/** /**
* @author xgc * @author xgc
**/ **/
@ -41,18 +45,26 @@ public class MilvusEntityConverter {
if (fieldAnnotation.isPrimaryKey()) { if (fieldAnnotation.isPrimaryKey()) {
collectionToPrimaryCache.collectionToPrimary.put(collectionName,fieldName); collectionToPrimaryCache.collectionToPrimary.put(collectionName,fieldName);
} }
AddFieldReq milvusField = AddFieldReq.builder() AddFieldReq.AddFieldReqBuilder<?, ?> builder = AddFieldReq.builder()
.fieldName(fieldName) .fieldName(fieldName)
.dataType(fieldAnnotation.dataType()) .dataType(fieldAnnotation.dataType())
.isPrimaryKey(fieldAnnotation.isPrimaryKey()) .isPrimaryKey(fieldAnnotation.isPrimaryKey())
.autoID(fieldAnnotation.autoID())
.description(StringUtils.isNotEmpty(fieldAnnotation.description()) ? fieldAnnotation.description() : null)
.dimension(fieldAnnotation.dimension())
.maxLength(fieldAnnotation.maxLength() > 0 ? fieldAnnotation.maxLength() : null)
.isPartitionKey(fieldAnnotation.isPartitionKey()) .isPartitionKey(fieldAnnotation.isPartitionKey())
.elementType(fieldAnnotation.elementType()) .elementType(fieldAnnotation.elementType())
.maxCapacity(fieldAnnotation.maxCapacity() > 0 ? fieldAnnotation.maxCapacity() : null) .autoID(fieldAnnotation.autoID());
.build(); if(StringUtils.isNotEmpty(fieldAnnotation.description())){
builder.description(fieldAnnotation.description());
}
if(fieldAnnotation.dimension()>0){
builder.dimension(fieldAnnotation.dimension());
}
if(fieldAnnotation.maxLength() > 0){
builder.maxLength(fieldAnnotation.maxLength());
}
if(fieldAnnotation.maxCapacity() > 0){
builder.maxCapacity(fieldAnnotation.maxCapacity());
}
AddFieldReq milvusField = builder.build();
milvusFields.add(milvusField); milvusFields.add(milvusField);
// 构建IndexParam对象 // 构建IndexParam对象
IndexParam indexParam = createIndexParam(field,fieldName); IndexParam indexParam = createIndexParam(field,fieldName);
@ -79,10 +91,17 @@ public class MilvusEntityConverter {
if (fieldAnnotation == null) { if (fieldAnnotation == null) {
return null; return null;
} }
Map<String,Object> map=new HashMap<>();
ExtraParam[] extraParams = fieldAnnotation.extraParams();
for (ExtraParam extraParam : extraParams) {
map.put(extraParam.key(),extraParam.value());
}
return IndexParam.builder() return IndexParam.builder()
.fieldName(fieldAnnotation.indexName().isEmpty() ? fieldName : fieldAnnotation.indexName()) .indexName(fieldAnnotation.indexName().isEmpty() ? fieldName : fieldAnnotation.indexName())
.fieldName(fieldName)
.indexType(fieldAnnotation.indexType()) .indexType(fieldAnnotation.indexType())
.metricType(fieldAnnotation.metricType()) // 默认使用L2距离根据需要调整 .metricType(fieldAnnotation.metricType()) // 默认使用L2距离根据需要调整
.extraParams(map)
.build(); .build();
} }

View File

@ -1,6 +1,9 @@
package io.github.javpower.milvus.plus.converter; package io.github.javpower.milvus.plus.converter;
import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectMapper;
import io.github.javpower.milvus.plus.cache.ConversionCache;
import io.github.javpower.milvus.plus.cache.MilvusCache;
import io.github.javpower.milvus.plus.cache.PropertyCache;
import io.github.javpower.milvus.plus.model.vo.MilvusResp; 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.MilvusResult;
import io.github.javpower.milvus.plus.model.vo.MilvusResultVo; import io.github.javpower.milvus.plus.model.vo.MilvusResultVo;
@ -9,6 +12,7 @@ import io.milvus.v2.service.vector.response.QueryResp;
import io.milvus.v2.service.vector.response.SearchResp; import io.milvus.v2.service.vector.response.SearchResp;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@ -21,6 +25,8 @@ public class SearchRespConverter {
private static final ObjectMapper objectMapper = new ObjectMapper(); private static final ObjectMapper objectMapper = new ObjectMapper();
public static <T> MilvusResp<MilvusResultVo<T>> convertSearchRespToMilvusResp(SearchResp searchResp, Class<T> entityType) { public static <T> MilvusResp<MilvusResultVo<T>> convertSearchRespToMilvusResp(SearchResp searchResp, Class<T> entityType) {
ConversionCache<?, ?> conversionCache = MilvusCache.milvusCache.get(entityType);
PropertyCache propertyCache = conversionCache.getPropertyCache();
List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults(); List<List<SearchResp.SearchResult>> searchResults = searchResp.getSearchResults();
// 将searchResults中的每个SearchResult转换为MilvusResult<T> // 将searchResults中的每个SearchResult转换为MilvusResult<T>
List<List<MilvusResult<T>>> milvusResults = searchResults.stream() List<List<MilvusResult<T>>> milvusResults = searchResults.stream()
@ -28,7 +34,13 @@ public class SearchRespConverter {
.map(searchResult -> { .map(searchResult -> {
try { try {
// 使用ObjectMapper将Map<String, Object>转换为Java实体类T // 使用ObjectMapper将Map<String, Object>转换为Java实体类T
T entity = objectMapper.convertValue(searchResult.getEntity(), entityType); 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());
}
T entity = objectMapper.convertValue(entityMap2, entityType);
MilvusResult<T> tMilvusResult = new MilvusResult<>(); MilvusResult<T> tMilvusResult = new MilvusResult<>();
tMilvusResult.setId(searchResult.getId()); tMilvusResult.setId(searchResult.getId());
tMilvusResult.setDistance(searchResult.getDistance()); tMilvusResult.setDistance(searchResult.getDistance());
@ -55,13 +67,20 @@ public class SearchRespConverter {
public static <T> MilvusResp<List<T>> convertGetRespToMilvusResp(GetResp getResp, Class<T> entityType) { public static <T> MilvusResp<List<T>> convertGetRespToMilvusResp(GetResp getResp, Class<T> entityType) {
// 解析GetResp中的查询结果 // 解析GetResp中的查询结果
ConversionCache<?, ?> conversionCache = MilvusCache.milvusCache.get(entityType);
PropertyCache propertyCache = conversionCache.getPropertyCache();
List<QueryResp.QueryResult> getResults = getResp.getResults; List<QueryResp.QueryResult> getResults = getResp.getResults;
List<T> entities = new ArrayList<>(); List<T> entities = new ArrayList<>();
// 遍历每个查询结果并将它们映射到Java实体类T的实例 // 遍历每个查询结果并将它们映射到Java实体类T的实例
for (QueryResp.QueryResult queryResult : getResults) { for (QueryResp.QueryResult queryResult : getResults) {
Map<String, Object> entityMap = queryResult.getEntity(); Map<String, Object> entityMap = queryResult.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映射到实体类T这个方法需要自定义实现 // 假设有一个方法可以从Map映射到实体类T这个方法需要自定义实现
T entity = objectMapper.convertValue(entityMap, entityType); T entity = objectMapper.convertValue(entityMap2, entityType);
entities.add(entity); entities.add(entity);
} }
// 创建MilvusResp对象并将实体列表作为其数据部分 // 创建MilvusResp对象并将实体列表作为其数据部分

View File

@ -4,8 +4,8 @@ import com.alibaba.fastjson.JSON;
import io.github.javpower.milvus.plus.cache.ConversionCache; import io.github.javpower.milvus.plus.cache.ConversionCache;
import io.github.javpower.milvus.plus.core.FieldFunction; import io.github.javpower.milvus.plus.core.FieldFunction;
import io.github.javpower.milvus.plus.model.vo.MilvusResp; 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.exception.MilvusException;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.DeleteReq; import io.milvus.v2.service.vector.request.DeleteReq;
import io.milvus.v2.service.vector.response.DeleteResp; import io.milvus.v2.service.vector.response.DeleteResp;
import lombok.Data; import lombok.Data;
@ -25,10 +25,10 @@ public class LambdaDeleteWrapper<T> extends AbstractChainWrapper<T> implements
private ConversionCache<?, ?> conversionCache; private ConversionCache<?, ?> conversionCache;
private Class<T> entityType; private Class<T> entityType;
private String collectionName; private String collectionName;
private MilvusClient client; private MilvusClientV2 client;
private List<Object> ids=new ArrayList<>(); private List<Object> ids=new ArrayList<>();
public LambdaDeleteWrapper(String collectionName, MilvusClient client, ConversionCache<?, ?> conversionCache, Class<T> entityType) { public LambdaDeleteWrapper(String collectionName, MilvusClientV2 client, ConversionCache<?, ?> conversionCache, Class<T> entityType) {
this.collectionName = collectionName; this.collectionName = collectionName;
this.client = client; this.client = client;
this.conversionCache=conversionCache; this.conversionCache=conversionCache;
@ -353,7 +353,7 @@ public class LambdaDeleteWrapper<T> extends AbstractChainWrapper<T> implements
public MilvusResp<DeleteResp> remove() throws MilvusException { public MilvusResp<DeleteResp> remove() throws MilvusException {
DeleteReq deleteReq = build(); DeleteReq deleteReq = build();
log.info("build remove param-->{}", JSON.toJSONString(deleteReq)); log.info("build remove param-->{}", JSON.toJSONString(deleteReq));
DeleteResp delete = client.client.delete(deleteReq); DeleteResp delete = client.delete(deleteReq);
MilvusResp<DeleteResp> resp=new MilvusResp(); MilvusResp<DeleteResp> resp=new MilvusResp();
resp.setData(delete); resp.setData(delete);
resp.setSuccess(true); resp.setSuccess(true);
@ -365,7 +365,7 @@ public class LambdaDeleteWrapper<T> extends AbstractChainWrapper<T> implements
} }
@Override @Override
public void init(String collectionName, MilvusClient client, ConversionCache conversionCache, Class entityType) { public void init(String collectionName, MilvusClientV2 client, ConversionCache conversionCache, Class entityType) {
setClient(client); setClient(client);
setCollectionName(collectionName); setCollectionName(collectionName);
setEntityType(entityType); setEntityType(entityType);

View File

@ -6,8 +6,8 @@ import io.github.javpower.milvus.plus.cache.ConversionCache;
import io.github.javpower.milvus.plus.cache.PropertyCache; import io.github.javpower.milvus.plus.cache.PropertyCache;
import io.github.javpower.milvus.plus.core.FieldFunction; import io.github.javpower.milvus.plus.core.FieldFunction;
import io.github.javpower.milvus.plus.model.vo.MilvusResp; 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.exception.MilvusException;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.InsertReq; import io.milvus.v2.service.vector.request.InsertReq;
import io.milvus.v2.service.vector.response.InsertResp; import io.milvus.v2.service.vector.response.InsertResp;
import lombok.Data; import lombok.Data;
@ -27,9 +27,9 @@ public class LambdaInsertWrapper<T> extends AbstractChainWrapper<T> implements
private ConversionCache<?, ?> conversionCache; private ConversionCache<?, ?> conversionCache;
private Class<T> entityType; private Class<T> entityType;
private String collectionName; private String collectionName;
private MilvusClient client; private MilvusClientV2 client;
private JSONObject entity=new JSONObject(); private JSONObject entity=new JSONObject();
public LambdaInsertWrapper(String collectionName, MilvusClient client, ConversionCache<?, ?> conversionCache, Class<T> entityType) { public LambdaInsertWrapper(String collectionName, MilvusClientV2 client, ConversionCache<?, ?> conversionCache, Class<T> entityType) {
this.collectionName = collectionName; this.collectionName = collectionName;
this.client = client; this.client = client;
this.conversionCache=conversionCache; this.conversionCache=conversionCache;
@ -66,7 +66,7 @@ public class LambdaInsertWrapper<T> extends AbstractChainWrapper<T> implements
.collectionName(collectionName) .collectionName(collectionName)
.data(jsonObjects) .data(jsonObjects)
.build(); .build();
InsertResp insert = client.client.insert(insertReq); InsertResp insert = client.insert(insertReq);
MilvusResp<InsertResp> resp=new MilvusResp(); MilvusResp<InsertResp> resp=new MilvusResp();
resp.setData(insert); resp.setData(insert);
resp.setSuccess(true); resp.setSuccess(true);
@ -92,7 +92,7 @@ public class LambdaInsertWrapper<T> extends AbstractChainWrapper<T> implements
} }
@Override @Override
public void init(String collectionName, MilvusClient client, ConversionCache conversionCache, Class entityType) { public void init(String collectionName, MilvusClientV2 client, ConversionCache conversionCache, Class entityType) {
setClient(client); setClient(client);
setCollectionName(collectionName); setCollectionName(collectionName);
setEntityType(entityType); setEntityType(entityType);

View File

@ -6,8 +6,8 @@ import io.github.javpower.milvus.plus.converter.SearchRespConverter;
import io.github.javpower.milvus.plus.core.FieldFunction; import io.github.javpower.milvus.plus.core.FieldFunction;
import io.github.javpower.milvus.plus.model.vo.MilvusResp; import io.github.javpower.milvus.plus.model.vo.MilvusResp;
import io.github.javpower.milvus.plus.model.vo.MilvusResultVo; 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.exception.MilvusException;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.common.ConsistencyLevel; import io.milvus.v2.common.ConsistencyLevel;
import io.milvus.v2.service.vector.request.GetReq; import io.milvus.v2.service.vector.request.GetReq;
import io.milvus.v2.service.vector.request.SearchReq; import io.milvus.v2.service.vector.request.SearchReq;
@ -40,9 +40,9 @@ public class LambdaSearchWrapper<T> extends AbstractChainWrapper<T> implements
private long guaranteeTimestamp; private long guaranteeTimestamp;
private ConsistencyLevel consistencyLevel; private ConsistencyLevel consistencyLevel;
private boolean ignoreGrowing; private boolean ignoreGrowing;
private MilvusClient client; private MilvusClientV2 client;
public LambdaSearchWrapper(String collectionName, MilvusClient client,ConversionCache<?, ?> conversionCache,Class<T> entityType) { public LambdaSearchWrapper(String collectionName, MilvusClientV2 client, ConversionCache<?, ?> conversionCache, Class<T> entityType) {
this.collectionName = collectionName; this.collectionName = collectionName;
this.client = client; this.client = client;
this.conversionCache=conversionCache; this.conversionCache=conversionCache;
@ -391,7 +391,7 @@ public class LambdaSearchWrapper<T> extends AbstractChainWrapper<T> implements
public MilvusResp<MilvusResultVo<T>> query() throws MilvusException { public MilvusResp<MilvusResultVo<T>> query() throws MilvusException {
SearchReq searchReq = build(); SearchReq searchReq = build();
log.info("build query param-->{}", JSON.toJSONString(searchReq)); log.info("build query param-->{}", JSON.toJSONString(searchReq));
SearchResp search = client.client.search(searchReq); SearchResp search = client.search(searchReq);
MilvusResp<MilvusResultVo<T>> tMilvusResp = SearchRespConverter.convertSearchRespToMilvusResp(search, entityType); MilvusResp<MilvusResultVo<T>> tMilvusResp = SearchRespConverter.convertSearchRespToMilvusResp(search, entityType);
return tMilvusResp; return tMilvusResp;
} }
@ -400,14 +400,13 @@ public class LambdaSearchWrapper<T> extends AbstractChainWrapper<T> implements
.collectionName(collectionName) .collectionName(collectionName)
.ids(Arrays.asList(ids)) .ids(Arrays.asList(ids))
.build(); .build();
GetResp getResp = client.client.get(getReq); GetResp getResp = client.get(getReq);
MilvusResp<List<T>> tMilvusResp = SearchRespConverter.convertGetRespToMilvusResp(getResp, entityType); MilvusResp<List<T>> tMilvusResp = SearchRespConverter.convertGetRespToMilvusResp(getResp, entityType);
return tMilvusResp; return tMilvusResp;
} }
@Override @Override
public void init(String collectionName, MilvusClient client, ConversionCache conversionCache, Class entityType) { public void init(String collectionName, MilvusClientV2 client, ConversionCache conversionCache, Class entityType) {
setClient(client); setClient(client);
setCollectionName(collectionName); setCollectionName(collectionName);
setEntityType(entityType); setEntityType(entityType);

View File

@ -7,8 +7,8 @@ import io.github.javpower.milvus.plus.cache.ConversionCache;
import io.github.javpower.milvus.plus.cache.PropertyCache; import io.github.javpower.milvus.plus.cache.PropertyCache;
import io.github.javpower.milvus.plus.core.FieldFunction; import io.github.javpower.milvus.plus.core.FieldFunction;
import io.github.javpower.milvus.plus.model.vo.MilvusResp; 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.exception.MilvusException;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.request.SearchReq; import io.milvus.v2.service.vector.request.SearchReq;
import io.milvus.v2.service.vector.request.UpsertReq; import io.milvus.v2.service.vector.request.UpsertReq;
import io.milvus.v2.service.vector.response.SearchResp; import io.milvus.v2.service.vector.response.SearchResp;
@ -29,9 +29,9 @@ public class LambdaUpdateWrapper<T> extends AbstractChainWrapper<T> implements
private ConversionCache<?, ?> conversionCache; private ConversionCache<?, ?> conversionCache;
private Class<T> entityType; private Class<T> entityType;
private String collectionName; private String collectionName;
private MilvusClient client; private MilvusClientV2 client;
public LambdaUpdateWrapper(String collectionName, MilvusClient client, ConversionCache<?, ?> conversionCache, Class<T> entityType) { public LambdaUpdateWrapper(String collectionName, MilvusClientV2 client, ConversionCache<?, ?> conversionCache, Class<T> entityType) {
this.collectionName = collectionName; this.collectionName = collectionName;
this.client = client; this.client = client;
this.conversionCache=conversionCache; this.conversionCache=conversionCache;
@ -327,7 +327,7 @@ public class LambdaUpdateWrapper<T> extends AbstractChainWrapper<T> implements
if (filterStr != null && !filterStr.isEmpty()) { if (filterStr != null && !filterStr.isEmpty()) {
SearchReq.SearchReqBuilder<?, ?> builder = SearchReq.builder() SearchReq.SearchReqBuilder<?, ?> builder = SearchReq.builder()
.collectionName(collectionName).filter(filterStr); .collectionName(collectionName).filter(filterStr);
SearchResp search = client.client.search(builder.build()); SearchResp search = client.search(builder.build());
return search; return search;
}else { }else {
return null; return null;
@ -383,7 +383,7 @@ public class LambdaUpdateWrapper<T> extends AbstractChainWrapper<T> implements
.collectionName(collectionName) .collectionName(collectionName)
.data(jsonObjects) .data(jsonObjects)
.build(); .build();
UpsertResp upsert = client.client.upsert(upsertReq); UpsertResp upsert = client.upsert(upsertReq);
MilvusResp<UpsertResp> resp=new MilvusResp(); MilvusResp<UpsertResp> resp=new MilvusResp();
resp.setData(upsert); resp.setData(upsert);
resp.setSuccess(true); resp.setSuccess(true);
@ -414,7 +414,7 @@ public class LambdaUpdateWrapper<T> extends AbstractChainWrapper<T> implements
} }
@Override @Override
public void init(String collectionName, MilvusClient client, ConversionCache conversionCache, Class entityType) { public void init(String collectionName, MilvusClientV2 client, ConversionCache conversionCache, Class entityType) {
setClient(client); setClient(client);
setCollectionName(collectionName); setCollectionName(collectionName);
setEntityType(entityType); setEntityType(entityType);

View File

@ -1,7 +1,7 @@
package io.github.javpower.milvus.plus.core.conditions; package io.github.javpower.milvus.plus.core.conditions;
import io.github.javpower.milvus.plus.cache.ConversionCache; import io.github.javpower.milvus.plus.cache.ConversionCache;
import io.github.javpower.milvus.plus.service.MilvusClient; import io.milvus.v2.client.MilvusClientV2;
/** /**
* 通用构建器接口 * 通用构建器接口
@ -9,6 +9,6 @@ import io.github.javpower.milvus.plus.service.MilvusClient;
* @param <T> 实体类型 * @param <T> 实体类型
*/ */
public interface Wrapper<W, T> { public interface Wrapper<W, T> {
void init(String collectionName, MilvusClient client, ConversionCache<?, ?> conversionCache, Class<T> entityType); void init(String collectionName, MilvusClientV2 client, ConversionCache<?, ?> conversionCache, Class<T> entityType);
W wrapper(); W wrapper();
} }

View File

@ -5,8 +5,8 @@ import io.github.javpower.milvus.plus.cache.ConversionCache;
import io.github.javpower.milvus.plus.cache.MilvusCache; import io.github.javpower.milvus.plus.cache.MilvusCache;
import io.github.javpower.milvus.plus.core.conditions.*; import io.github.javpower.milvus.plus.core.conditions.*;
import io.github.javpower.milvus.plus.model.vo.MilvusResp; import io.github.javpower.milvus.plus.model.vo.MilvusResp;
import io.github.javpower.milvus.plus.service.MilvusClient;
import io.github.javpower.milvus.plus.util.SpringUtils; import io.github.javpower.milvus.plus.util.SpringUtils;
import io.milvus.v2.client.MilvusClientV2;
import io.milvus.v2.service.vector.response.DeleteResp; import io.milvus.v2.service.vector.response.DeleteResp;
import io.milvus.v2.service.vector.response.InsertResp; import io.milvus.v2.service.vector.response.InsertResp;
import io.milvus.v2.service.vector.response.UpsertResp; import io.milvus.v2.service.vector.response.UpsertResp;
@ -91,7 +91,7 @@ public class MilvusMapper<T> {
ConversionCache<?, ?> conversionCache = MilvusCache.milvusCache.get(entityType); ConversionCache<?, ?> conversionCache = MilvusCache.milvusCache.get(entityType);
String collectionName = conversionCache == null ? null : conversionCache.getCollectionName(); String collectionName = conversionCache == null ? null : conversionCache.getCollectionName();
// 使用SpringUtil获取MilvusClient实例 // 使用SpringUtil获取MilvusClient实例
MilvusClient client = SpringUtils.getBean(MilvusClient.class); MilvusClientV2 client = SpringUtils.getBean(MilvusClientV2.class);
// 初始化构建器实例 // 初始化构建器实例
wrapper.init(collectionName, client, conversionCache, entityType); wrapper.init(collectionName, client, conversionCache, entityType);
return wrapper.wrapper(); return wrapper.wrapper();

View File

@ -1,19 +0,0 @@
package io.github.javpower.milvus.plus.service;
import io.milvus.v2.client.MilvusClientV2;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
/**
* @author xgc
**/
@Service
public class MilvusClient implements AutoCloseable {
@Autowired(required = false)
public MilvusClientV2 client;
@Override
public void close() throws InterruptedException {
client.close(10);
}
}

View File

@ -1,77 +0,0 @@
package io.github.javpower.milvus.plus.service;
import io.github.javpower.milvus.plus.builder.CollectionSchemaBuilder;
import io.github.javpower.milvus.plus.converter.MilvusEntityConverter;
import io.github.javpower.milvus.plus.model.MilvusEntity;
import io.milvus.exception.MilvusException;
import io.milvus.v2.common.IndexParam;
import io.milvus.v2.service.collection.request.AddFieldReq;
import io.milvus.v2.service.collection.request.DescribeCollectionReq;
import io.milvus.v2.service.collection.request.DropCollectionReq;
import io.milvus.v2.service.collection.request.HasCollectionReq;
import io.milvus.v2.service.collection.response.DescribeCollectionResp;
import org.springframework.stereotype.Service;
import java.util.HashSet;
import java.util.List;
import java.util.stream.Collectors;
/**
* @author xgc
**/
@Service
public class MilvusCollectionService {
private final MilvusClient milvusClient;
public MilvusCollectionService(MilvusClient milvusClient) {
this.milvusClient = milvusClient;
}
public void performBusinessLogic(List<Class<?>> annotatedClasses) {
for (Class<?> milvusClass : annotatedClasses) {
MilvusEntity milvusEntity = MilvusEntityConverter.convert(milvusClass);
try {
String collectionName = milvusEntity.getCollectionName();
// 检查集合是否存在
boolean collectionExists = milvusClient.client.hasCollection(
HasCollectionReq.builder().collectionName(collectionName).build()
);
if (collectionExists) {
// 获取集合的详细信息
DescribeCollectionResp collectionInfo = milvusClient.client.describeCollection(
DescribeCollectionReq.builder().collectionName(collectionName).build()
);
// 检查字段是否一致这里需要实现字段比较逻辑
List<String> existingFieldNames = collectionInfo.getFieldNames();
List<AddFieldReq> requiredFields = milvusEntity.getMilvusFields();
List<String> requiredFieldNames = requiredFields.stream().map(AddFieldReq::getFieldName).collect(Collectors.toList());
if (!new HashSet<>(existingFieldNames).containsAll(requiredFieldNames) || !new HashSet<>(requiredFieldNames).containsAll(existingFieldNames)) {
// 字段不一致删除并重新创建集合
milvusClient.client.dropCollection(
DropCollectionReq.builder().collectionName(collectionName).build()
);
// 创建新集合
create(milvusEntity);
}
} else {
// 创建新集合
create(milvusEntity);
}
} catch (MilvusException e) {
throw new RuntimeException("Error handling Milvus collection", e);
}
}
}
private void create(MilvusEntity milvusEntity){
// 创建新集合
CollectionSchemaBuilder schemaBuilder = new CollectionSchemaBuilder(
milvusEntity.getCollectionName(), milvusClient
);
schemaBuilder.addField(milvusEntity.getMilvusFields().toArray(new AddFieldReq[0]));
List<IndexParam> indexParams = milvusEntity.getIndexParams();
schemaBuilder.createSchema();
if (indexParams != null && !indexParams.isEmpty()) {
schemaBuilder.createIndex(indexParams);
}
}
}