Browse Source

Add enableDynamicField flag in V2 CollectionSchema (#1114)

Signed-off-by: yhmo <yihua.mo@zilliz.com>
groot 8 months ago
parent
commit
dd43f2368e

+ 1 - 3
src/main/java/io/milvus/v2/service/collection/CollectionService.java

@@ -34,9 +34,7 @@ import org.apache.commons.collections4.CollectionUtils;
 import org.apache.commons.lang3.StringUtils;
 
 import java.util.Collections;
-import java.util.HashMap;
 import java.util.List;
-import java.util.Map;
 
 public class CollectionService extends BaseService {
     public IndexService indexService = new IndexService();
@@ -115,7 +113,7 @@ public class CollectionService extends BaseService {
         CollectionSchema grpcSchema = CollectionSchema.newBuilder()
                 .setName(request.getCollectionName())
                 .setDescription(request.getDescription())
-                .setEnableDynamicField(request.getEnableDynamicField())
+                .setEnableDynamicField(request.getCollectionSchema().isEnableDynamicField())
                 .build();
         for (CreateCollectionReq.FieldSchema fieldSchema : request.getCollectionSchema().getFieldSchemaList()) {
             grpcSchema = grpcSchema.toBuilder().addFields(SchemaUtils.convertToGrpcFieldSchema(fieldSchema)).build();

+ 25 - 0
src/main/java/io/milvus/v2/service/collection/request/CreateCollectionReq.java

@@ -55,6 +55,8 @@ public class CreateCollectionReq {
     private Boolean autoID = Boolean.FALSE;
 
     // used by quickly create collections and create collections with schema
+    // Note: This property is only for fast creating collection. If user use CollectionSchema to create a collection,
+    //       the CollectionSchema.enableDynamicField must equal to CreateCollectionReq.enableDynamicField.
     @Builder.Default
     private Boolean enableDynamicField = Boolean.TRUE;
     @Builder.Default
@@ -83,6 +85,27 @@ public class CreateCollectionReq {
             this.indexParams$set = true;
             return self();
         }
+
+        public B enableDynamicField(Boolean enableDynamicField) {
+            if (this.collectionSchema != null && (this.collectionSchema.isEnableDynamicField() != enableDynamicField)) {
+                throw new MilvusClientException(ErrorCode.INVALID_PARAMS,
+                        "The enableDynamicField flag has been set by CollectionSchema, not allow to set different value by enableDynamicField().");
+            }
+            this.enableDynamicField$value = enableDynamicField;
+            this.enableDynamicField$set = true;
+            return self();
+        }
+
+        public B collectionSchema(CollectionSchema collectionSchema) {
+            if (this.enableDynamicField$set && (collectionSchema.isEnableDynamicField() != this.enableDynamicField$value)) {
+                throw new MilvusClientException(ErrorCode.INVALID_PARAMS,
+                        "The enableDynamicField flag has been set by enableDynamicField(), not allow to set different value by collectionSchema.");
+            }
+            this.collectionSchema = collectionSchema;
+            this.enableDynamicField$value = collectionSchema.isEnableDynamicField();
+            this.enableDynamicField$set = true;
+            return self();
+        }
     }
 
     @Data
@@ -90,6 +113,8 @@ public class CreateCollectionReq {
     public static class CollectionSchema {
         @Builder.Default
         private List<CreateCollectionReq.FieldSchema> fieldSchemaList = new ArrayList<>();
+        @Builder.Default
+        private boolean enableDynamicField = false;
 
         public CollectionSchema addField(AddFieldReq addFieldReq) {
             CreateCollectionReq.FieldSchema fieldSchema = FieldSchema.builder()

+ 1 - 1
src/test/java/io/milvus/v2/client/MilvusClientV2DockerTest.java

@@ -485,7 +485,7 @@ class MilvusClientV2DockerTest {
         Assertions.assertEquals(2, descResp.getNumOfPartitions());
         Assertions.assertEquals(1, descResp.getVectorFieldNames().size());
         Assertions.assertEquals("id", descResp.getPrimaryFieldName());
-        Assertions.assertTrue(descResp.getEnableDynamicField());
+        Assertions.assertFalse(descResp.getEnableDynamicField()); // from v2.4.6, we add this flag in CollectionSchema, default value is False(follow the pymilvus behavior)
         Assertions.assertFalse(descResp.getAutoID());
 
         List<String> fieldNames = descResp.getFieldNames();

+ 41 - 2
src/test/java/io/milvus/v2/service/collection/CollectionTest.java

@@ -22,19 +22,20 @@ package io.milvus.v2.service.collection;
 import io.milvus.v2.BaseTest;
 import io.milvus.v2.common.DataType;
 import io.milvus.v2.common.IndexParam;
+import io.milvus.v2.exception.MilvusClientException;
 import io.milvus.v2.service.collection.request.*;
 import io.milvus.v2.service.collection.response.DescribeCollectionResp;
 import io.milvus.v2.service.collection.response.GetCollectionStatsResp;
 import io.milvus.v2.service.collection.response.ListCollectionsResp;
+import org.junit.jupiter.api.Assertions;
 import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
-import org.testcontainers.shaded.org.checkerframework.checker.units.qual.A;
 
 import java.util.Arrays;
-import java.util.Collections;
 
 import static org.junit.Assert.assertEquals;
+import static org.junit.jupiter.api.Assertions.assertThrows;
 
 class CollectionTest extends BaseTest {
     Logger logger = LoggerFactory.getLogger(CollectionTest.class);
@@ -53,6 +54,44 @@ class CollectionTest extends BaseTest {
         client_v2.createCollection(req);
     }
 
+    @Test
+    void testEnableDynamicSchema() {
+        CreateCollectionReq req = CreateCollectionReq.builder()
+                .collectionName("test2")
+                .dimension(2)
+                .enableDynamicField(false)
+                .build();
+        Assertions.assertFalse(req.getEnableDynamicField());
+
+        CreateCollectionReq.CollectionSchema collectionSchema = CreateCollectionReq.CollectionSchema.builder()
+                .enableDynamicField(true)
+                .build();
+        collectionSchema
+                .addField(AddFieldReq.builder().fieldName("id").dataType(DataType.Int64).build())
+                .addField(AddFieldReq.builder().fieldName("vector").dataType(DataType.FloatVector).dimension(2).build());
+
+        req = CreateCollectionReq.builder()
+                .collectionName("test")
+                .collectionSchema(collectionSchema)
+                .build();
+        Assertions.assertTrue(req.getEnableDynamicField());
+        Assertions.assertTrue(req.getCollectionSchema().isEnableDynamicField());
+
+        assertThrows(MilvusClientException.class, () ->CreateCollectionReq.builder()
+                .collectionName("test")
+                .enableDynamicField(false)
+                .collectionSchema(collectionSchema)
+                .build()
+        );
+
+        assertThrows(MilvusClientException.class, () ->CreateCollectionReq.builder()
+                .collectionName("test")
+                .collectionSchema(collectionSchema)
+                .enableDynamicField(false)
+                .build()
+        );
+    }
+
     @Test
     void testCreateCollectionWithSchema() {