Browse Source

add testcase for json path index (#1338)

Signed-off-by: yongpengli-z <yongpeng.li@zilliz.com>
yongpengli-z 1 month ago
parent
commit
092e98fdfc

+ 1 - 1
tests/milvustestv2/pom.xml

@@ -101,7 +101,7 @@
         <dependency>
             <groupId>io.milvus</groupId>
             <artifactId>milvus-sdk-java-bulkwriter</artifactId>
-            <version>2.5.4</version>
+            <version>2.5.5</version>
         </dependency>
     </dependencies>
     <build>

+ 4 - 0
tests/milvustestv2/src/main/java/com/zilliz/milvustestv2/common/CommonData.java

@@ -27,12 +27,16 @@ public class CommonData {
     public static String fieldVarchar="fieldVarchar";
     public static String fieldFloat="fieldFloat";
     public static String fieldJson="fieldJson";
+
+    public static String fieldDynamic="fieldDynamic";
+    public static String fieldDynamicNotExist="fieldDynamicNotExist";
     public static String fieldFloatVector="fieldFloatVector";
     public static String fieldBinaryVector="fieldBinaryVector";
     public static String fieldFloat16Vector="fieldFloat16Vector";
     public static String fieldBF16Vector="fieldBF16Vector";
     public static String fieldSparseVector="fieldSparseVector";
 
+
     public static String partitionName="partitionName";
     // 快速创建时候的默认向量filed
     public static String simpleVector="vector";

+ 269 - 3
tests/milvustestv2/src/main/java/com/zilliz/milvustestv2/common/CommonFunction.java

@@ -9,6 +9,8 @@ import com.zilliz.milvustestv2.utils.GenerateUtil;
 import com.zilliz.milvustestv2.utils.JsonObjectUtil;
 import com.zilliz.milvustestv2.utils.MathUtil;
 import com.zilliz.milvustestv2.utils.PropertyFilesUtil;
+import io.milvus.bulkwriter.LocalBulkWriter;
+import io.milvus.bulkwriter.LocalBulkWriterParam;
 import io.milvus.bulkwriter.RemoteBulkWriter;
 import io.milvus.bulkwriter.RemoteBulkWriterParam;
 import io.milvus.bulkwriter.common.clientenum.BulkFileType;
@@ -32,12 +34,19 @@ import io.milvus.v2.service.vector.request.SearchReq;
 import io.milvus.v2.service.vector.request.data.*;
 import io.milvus.v2.service.vector.response.InsertResp;
 import io.milvus.v2.service.vector.response.SearchResp;
+import io.minio.BucketExistsArgs;
+import io.minio.MakeBucketArgs;
+import io.minio.MinioClient;
+import io.minio.UploadObjectArgs;
+import io.minio.errors.*;
 import lombok.NonNull;
 import lombok.extern.slf4j.Slf4j;
 
 import javax.annotation.Nullable;
 import java.io.IOException;
 import java.nio.ByteBuffer;
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
 import java.util.*;
 import java.util.stream.Collectors;
 
@@ -266,6 +275,114 @@ public class CommonFunction {
         log.info("create collection:" + collectionName);
         return collectionName;
     }
+    public static String createNewCollectionWithDynamic(int dim, String collectionName, DataType vectorType) {
+        if (collectionName == null || collectionName.equals("")) {
+            collectionName = "Collection_" + GenerateUtil.getRandomString(10);
+        }
+        CreateCollectionReq.FieldSchema fieldInt64 = CreateCollectionReq.FieldSchema.builder()
+                .autoID(false)
+                .dataType(io.milvus.v2.common.DataType.Int64)
+                .isPrimaryKey(true)
+                .name(CommonData.fieldInt64)
+                .build();
+        CreateCollectionReq.FieldSchema fieldInt32 = CreateCollectionReq.FieldSchema.builder()
+                .dataType(DataType.Int32)
+                .name(CommonData.fieldInt32)
+                .isPrimaryKey(false)
+                .build();
+        CreateCollectionReq.FieldSchema fieldInt16 = CreateCollectionReq.FieldSchema.builder()
+                .dataType(DataType.Int16)
+                .name(CommonData.fieldInt16)
+                .isPrimaryKey(false)
+                .build();
+        CreateCollectionReq.FieldSchema fieldInt8 = CreateCollectionReq.FieldSchema.builder()
+                .dataType(DataType.Int8)
+                .name(CommonData.fieldInt8)
+                .isPrimaryKey(false)
+                .build();
+        CreateCollectionReq.FieldSchema fieldDouble = CreateCollectionReq.FieldSchema.builder()
+                .dataType(DataType.Double)
+                .name(CommonData.fieldDouble)
+                .isPrimaryKey(false)
+                .build();
+        CreateCollectionReq.FieldSchema fieldArray = CreateCollectionReq.FieldSchema.builder()
+                .dataType(DataType.Array)
+                .name(CommonData.fieldArray)
+                .elementType(DataType.Int64)
+                .maxCapacity(100)
+                .isPrimaryKey(false)
+                .build();
+        CreateCollectionReq.FieldSchema fieldBool = CreateCollectionReq.FieldSchema.builder()
+                .dataType(DataType.Bool)
+                .name(CommonData.fieldBool)
+                .isPrimaryKey(false)
+                .build();
+        CreateCollectionReq.FieldSchema fieldVarchar = CreateCollectionReq.FieldSchema.builder()
+                .dataType(DataType.VarChar)
+                .name(CommonData.fieldVarchar)
+                .isPrimaryKey(false)
+                .maxLength(100)
+                .build();
+        CreateCollectionReq.FieldSchema fieldFloat = CreateCollectionReq.FieldSchema.builder()
+                .dataType(DataType.Float)
+                .name(CommonData.fieldFloat)
+                .isPrimaryKey(false)
+                .build();
+        CreateCollectionReq.FieldSchema fieldJson = CreateCollectionReq.FieldSchema.builder()
+                .dataType(DataType.JSON)
+                .name(CommonData.fieldJson)
+                .isPrimaryKey(false)
+                .build();
+        CreateCollectionReq.FieldSchema fieldVector = CreateCollectionReq.FieldSchema.builder()
+                .dataType(vectorType)
+                .isPrimaryKey(false)
+                .build();
+        if (vectorType == DataType.FloatVector) {
+            fieldVector.setDimension(dim);
+            fieldVector.setName(CommonData.fieldFloatVector);
+        }
+        if (vectorType == DataType.BinaryVector) {
+            fieldVector.setDimension(dim);
+            fieldVector.setName(CommonData.fieldBinaryVector);
+        }
+        if (vectorType == DataType.Float16Vector) {
+            fieldVector.setDimension(dim);
+            fieldVector.setName(CommonData.fieldFloat16Vector);
+        }
+        if (vectorType == DataType.BFloat16Vector) {
+            fieldVector.setDimension(dim);
+            fieldVector.setName(CommonData.fieldBF16Vector);
+        }
+        if (vectorType == DataType.SparseFloatVector) {
+            fieldVector.setName(CommonData.fieldSparseVector);
+        }
+        List<CreateCollectionReq.FieldSchema> fieldSchemaList = new ArrayList<>();
+        fieldSchemaList.add(fieldInt64);
+        fieldSchemaList.add(fieldInt32);
+        fieldSchemaList.add(fieldInt16);
+        fieldSchemaList.add(fieldInt8);
+        fieldSchemaList.add(fieldFloat);
+        fieldSchemaList.add(fieldDouble);
+        fieldSchemaList.add(fieldArray);
+        fieldSchemaList.add(fieldBool);
+        fieldSchemaList.add(fieldJson);
+        fieldSchemaList.add(fieldVarchar);
+        fieldSchemaList.add(fieldVector);
+        CreateCollectionReq.CollectionSchema collectionSchema = CreateCollectionReq.CollectionSchema.builder()
+                .fieldSchemaList(fieldSchemaList)
+                .enableDynamicField(true)
+                .build();
+        CreateCollectionReq createCollectionReq = CreateCollectionReq.builder()
+                .collectionSchema(collectionSchema)
+                .collectionName(collectionName)
+                .enableDynamicField(true)
+                .description("collection desc")
+                .numShards(1)
+                .build();
+        milvusClientV2.createCollection(createCollectionReq);
+        log.info("create collection with dynamic field:" + collectionName);
+        return collectionName;
+    }
 
     /**
      * 创建包含nullable列的collection
@@ -704,6 +821,67 @@ public class CommonFunction {
         return jsonList;
     }
 
+    public static List<JsonObject> generateDefaultDataWithDynamic(long startId, long num, int dim, DataType vectorType) {
+        List<JsonObject> jsonList = new ArrayList<>();
+        Random ran = new Random();
+        Gson gson = new Gson();
+        for (long i = startId; i < (num + startId); i++) {
+            JsonObject row = new JsonObject();
+            row.addProperty(CommonData.fieldInt64, i);
+            row.addProperty(CommonData.fieldInt32, (int) i % 32767);
+            row.addProperty(CommonData.fieldInt16, (int) i % 32767);
+            row.addProperty(CommonData.fieldInt8, (short) i % 127);
+            row.addProperty(CommonData.fieldDouble, (double) i);
+            row.add(CommonData.fieldArray, gson.toJsonTree(Arrays.asList(i, i + 1, i + 2)));
+            row.addProperty(CommonData.fieldBool, i % 2 == 0);
+            row.addProperty(CommonData.fieldVarchar, "Str" + i);
+            row.addProperty(CommonData.fieldFloat, (float) i);
+            // 判断vectorType
+            if (vectorType == DataType.FloatVector) {
+                List<Float> vector = new ArrayList<>();
+                for (int k = 0; k < dim; ++k) {
+                    vector.add(ran.nextFloat());
+                }
+                row.add(CommonData.fieldFloatVector, gson.toJsonTree(vector));
+            }
+            if (vectorType == DataType.BinaryVector) {
+                row.add(CommonData.fieldBinaryVector, gson.toJsonTree(generateBinaryVector(dim).array()));
+            }
+            if (vectorType == DataType.Float16Vector) {
+                row.add(CommonData.fieldFloat16Vector, gson.toJsonTree(generateFloat16Vector(dim).array()));
+            }
+            if (vectorType == DataType.BFloat16Vector) {
+                row.add(CommonData.fieldBF16Vector, gson.toJsonTree(generateBF16Vector(dim).array()));
+            }
+            if (vectorType == DataType.SparseFloatVector) {
+                row.add(CommonData.fieldSparseVector, gson.toJsonTree(generateSparseVector(dim)));
+            }
+
+            JsonObject json = new JsonObject();
+            json.addProperty(CommonData.fieldInt64, (int) i % 32767);
+            json.addProperty(CommonData.fieldInt32, (int) i % 32767);
+            json.addProperty(CommonData.fieldDouble, (double) i);
+            json.add(CommonData.fieldArray, gson.toJsonTree(Arrays.asList(i, i + 1, i + 2)));
+            json.addProperty(CommonData.fieldBool, i % 2 == 0);
+            json.addProperty(CommonData.fieldVarchar, "Str" + i);
+            json.addProperty(CommonData.fieldFloat, (float) i);
+            row.add(CommonData.fieldJson, json);
+            // dynamic field
+            JsonObject jsonDynamic = new JsonObject();
+            json.addProperty(CommonData.fieldInt64, (int) i % 32767);
+            json.addProperty(CommonData.fieldInt32, (int) i % 32767);
+            json.addProperty(CommonData.fieldDouble, (double) i);
+            json.add(CommonData.fieldArray, gson.toJsonTree(Arrays.asList(i, i + 1, i + 2)));
+            json.addProperty(CommonData.fieldBool, i % 2 == 0);
+            json.addProperty(CommonData.fieldVarchar, "Str" + i);
+            json.addProperty(CommonData.fieldFloat, (float) i);
+            row.add(CommonData.fieldDynamic, json);
+
+            jsonList.add(row);
+        }
+        return jsonList;
+    }
+
     /**
      * 为快速生成的collection提供导入数据
      *
@@ -1550,7 +1728,7 @@ public class CommonFunction {
             }
         });
         System.out.printf("%s rows appends%n", remoteBulkWriter.getTotalRowCount());
-        System.out.printf("%s rows in buffer not flushed%n", remoteBulkWriter.getBufferRowCount());
+        System.out.printf("%s rows in buffer not flushed%n", remoteBulkWriter.getTotalRowCount());
         try {
             remoteBulkWriter.commit(false);
         } catch (InterruptedException e) {
@@ -1562,7 +1740,8 @@ public class CommonFunction {
     }
 
     /**
-     * 为开源提供bulk writer
+     * 为开源提供 remote bulk writer
+     * RemoteBulkWriterParam = LocalBulkWriterParam + uploadObject + clearData
      *
      * @param collectionSchema
      * @param bulkFileType
@@ -1581,7 +1760,7 @@ public class CommonFunction {
                 .withCollectionSchema(collectionSchema)
                 .withRemotePath("bulk_data")
                 .withFileType(bulkFileType)
-                .withChunkSize(512 * 1024 * 1024)
+                .withChunkSize(5 * 1024 * 1024 * 1024L)
                 .withConnectParam(connectParam)
                 .build();
         RemoteBulkWriter remoteBulkWriter = null;
@@ -1593,6 +1772,93 @@ public class CommonFunction {
         return remoteBulkWriter;
     }
 
+
+    private static LocalBulkWriter buildLocalBulkWriter(CreateCollectionReq.CollectionSchema collectionSchema, BulkFileType bulkFileType) {
+        LocalBulkWriterParam bulkWriterParam = LocalBulkWriterParam.newBuilder()
+                .withCollectionSchema(collectionSchema)
+                .withLocalPath("/tmp/bulk_writer")
+                .withFileType(bulkFileType)
+                .withChunkSize(5 * 1024 * 1024 * 1024L)
+                .build();
+        LocalBulkWriter localBulkWriter;
+        try {
+            localBulkWriter = new LocalBulkWriter(bulkWriterParam);
+        } catch (IOException e) {
+            throw new RuntimeException(e);
+        }
+        return localBulkWriter;
+    }
+
+    public static List<List<String>> providerLocalBatchFiles(String collection, BulkFileType bulkFileType, long count) {
+        DescribeCollectionResp describeCollectionResp = milvusClientV2.describeCollection(DescribeCollectionReq.builder().collectionName(collection).build());
+        CreateCollectionReq.CollectionSchema collectionSchema = describeCollectionResp.getCollectionSchema();
+        LocalBulkWriter localBulkWriter = buildLocalBulkWriter(collectionSchema, bulkFileType);
+        List<JsonObject> jsonObjects = CommonFunction.genCommonData(collection, count);
+        for (JsonObject jsonObject : jsonObjects) {
+            try {
+                localBulkWriter.appendRow(jsonObject);
+            } catch (IOException | InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        System.out.printf("%s rows appends%n", localBulkWriter.getTotalRowCount());
+        System.out.printf("%s rows in buffer not flushed%n", localBulkWriter.getTotalRowCount());
+
+        try {
+            localBulkWriter.commit(false);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+        List<List<String>> batchFiles = localBulkWriter.getBatchFiles();
+        System.out.printf("Local writer done! output remote files: %s%n", batchFiles);
+        return batchFiles;
+    }
+
+    // minio上传--copy from v1
+    public static void multiFilesUpload(String path, List<List<String>> batchFiles) {
+
+        MinioClient minioClient =
+                MinioClient.builder()
+                        .endpoint(System.getProperty("minio") == null ? PropertyFilesUtil.getRunValue("minio") : System.getProperty("minio"))
+                        .credentials("minioadmin", "minioadmin")
+                        .build();
+        // Make 'jsonBucket' bucket if not exist.
+        boolean found = false;
+        try {
+            found = minioClient.bucketExists(BucketExistsArgs.builder().bucket("milvus-bucket").build());
+            if (!found) {
+                // Make a new bucket called 'jsonBucket'.
+                minioClient.makeBucket(MakeBucketArgs.builder().bucket("milvus-bucket").build());
+            } else {
+                System.out.println("Bucket 'milvus-bucket' already exists.");
+            }
+
+            List<String> fileNameList=new ArrayList<>();
+            for (List<String> batchFileList : batchFiles) {
+                fileNameList.addAll(batchFileList);
+            }
+            for (String fileName : fileNameList) {
+                minioClient.uploadObject(
+                        UploadObjectArgs.builder()
+                                .bucket("milvus-bucket")
+                                .object( fileName)
+                                .filename( fileName)
+                                .build());
+                System.out.println(
+                        "'"
+                                + path
+                                + fileName
+                                + "' is successfully uploaded as "
+                                + "object '"
+                                + fileName
+                                + "' to bucket 'milvus-bucket'.");
+            }
+        } catch (Exception e) {
+            System.out.println(e.getMessage());
+        }
+
+    }
+
 }
 
 

+ 72 - 7
tests/milvustestv2/src/test/java/com/zilliz/milvustestv2/bulk/BulkImportTest.java

@@ -8,8 +8,13 @@ import com.zilliz.milvustestv2.common.CommonFunction;
 import com.zilliz.milvustestv2.utils.PropertyFilesUtil;
 import io.milvus.bulkwriter.BulkImport;
 import io.milvus.bulkwriter.common.clientenum.BulkFileType;
+import io.milvus.bulkwriter.request.describe.MilvusDescribeImportRequest;
 import io.milvus.bulkwriter.request.import_.MilvusImportRequest;
 import io.milvus.v2.service.collection.request.DropCollectionReq;
+import io.milvus.v2.service.collection.request.GetCollectionStatsReq;
+import io.milvus.v2.service.collection.response.GetCollectionStatsResp;
+import io.milvus.v2.service.vector.request.GetReq;
+import io.milvus.v2.service.vector.response.GetResp;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
@@ -24,7 +29,7 @@ public class BulkImportTest extends BaseTest {
 
     @BeforeClass(alwaysRun = true)
     public void initTestData() {
-        collectionName = CommonFunction.createSimpleCollection(CommonData.dim, null,false);
+        collectionName = CommonFunction.createSimpleCollection(CommonData.dim, null, false);
     }
 
     @AfterClass(alwaysRun = true)
@@ -33,25 +38,85 @@ public class BulkImportTest extends BaseTest {
                 .collectionName(collectionName).build());
     }
 
-    @Test(description = "bulk import", groups = {"L1"})
-    public void bulkImport() {
-        List<List<String>> batchFiles = CommonFunction.providerBatchFiles(collectionName, BulkFileType.PARQUET,10000);
-
+    @Test(description = "remote bulk import", groups = {"L1"})
+    public void remoteBulkImport() {
+        List<List<String>> batchFiles = CommonFunction.providerBatchFiles(collectionName, BulkFileType.PARQUET, CommonData.numberEntities);
         MilvusImportRequest milvusImportRequest = MilvusImportRequest.builder()
                 .collectionName(collectionName)
                 .files(batchFiles)
                 .build();
         String bulkImportResult = BulkImport.bulkImport(
-                System.getProperty("uri")== null? PropertyFilesUtil.getRunValue("uri"):System.getProperty("uri"),
+                System.getProperty("uri") == null ? PropertyFilesUtil.getRunValue("uri") : System.getProperty("uri"),
                 milvusImportRequest);
-        JsonObject bulkImportJO= JsonParser.parseString(bulkImportResult).getAsJsonObject();
+        JsonObject bulkImportJO = JsonParser.parseString(bulkImportResult).getAsJsonObject();
         String jobId = bulkImportJO.getAsJsonObject("data").get("jobId").getAsString();
         System.out.println(jobId);
         Assert.assertNotNull(jobId);
+        // 遍历导入进程
+        String status = "";
+        int i = 0;
+        while (!status.equalsIgnoreCase("Completed") && i < 10) {
+
+            MilvusDescribeImportRequest request = MilvusDescribeImportRequest.builder()
+                    .jobId(jobId)
+                    .build();
+            String importProgress = BulkImport.getImportProgress(System.getProperty("uri") == null ? PropertyFilesUtil.getRunValue("uri") : System.getProperty("uri"),
+                    request);
+            JsonObject jsonObject = JsonParser.parseString(importProgress).getAsJsonObject();
+            status = jsonObject.getAsJsonObject("data").get("state").getAsString();
+            i++;
+            try {
+                Thread.sleep(5000);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+        GetCollectionStatsResp collectionStats = milvusClientV2.getCollectionStats(GetCollectionStatsReq.builder().collectionName(collectionName).build());
+        System.out.println(collectionStats);
 
     }
 
+    @Test(description = "local bulk import", groups = {"L2"})
+    public void localBulkImport() {
+        List<List<String>> batchFiles = CommonFunction.providerLocalBatchFiles(collectionName, BulkFileType.PARQUET, CommonData.numberEntities);
+        // 上传minio
+        CommonFunction.multiFilesUpload("", batchFiles);
 
+        MilvusImportRequest milvusImportRequest = MilvusImportRequest.builder()
+                .collectionName(collectionName)
+                .files(batchFiles)
+                .build();
+        String bulkImportResult = BulkImport.bulkImport(
+                System.getProperty("uri") == null ? PropertyFilesUtil.getRunValue("uri") : System.getProperty("uri"),
+                milvusImportRequest);
+        JsonObject bulkImportJO = JsonParser.parseString(bulkImportResult).getAsJsonObject();
+        String jobId = bulkImportJO.getAsJsonObject("data").get("jobId").getAsString();
+        System.out.println(jobId);
+        Assert.assertNotNull(jobId);
+        // 遍历导入进程
+        String status = "";
+        int i = 0;
+        while (!status.equalsIgnoreCase("Completed") && i < 10) {
+
+            MilvusDescribeImportRequest request = MilvusDescribeImportRequest.builder()
+                    .jobId(jobId)
+                    .build();
+            String importProgress = BulkImport.getImportProgress(System.getProperty("uri") == null ? PropertyFilesUtil.getRunValue("uri") : System.getProperty("uri"),
+                    request);
+            JsonObject jsonObject = JsonParser.parseString(importProgress).getAsJsonObject();
+            status = jsonObject.getAsJsonObject("data").get("state").getAsString();
+            i++;
+            try {
+                Thread.sleep(5000);
+            } catch (InterruptedException e) {
+                throw new RuntimeException(e);
+            }
+        }
+
+        GetCollectionStatsResp collectionStats = milvusClientV2.getCollectionStats(GetCollectionStatsReq.builder().collectionName(collectionName).build());
+        Assert.assertTrue(collectionStats.getNumOfEntities() == CommonData.numberEntities);
+
+    }
 
 
 }

+ 143 - 10
tests/milvustestv2/src/test/java/com/zilliz/milvustestv2/database/CreateDatabaseTest.java

@@ -1,45 +1,70 @@
 package com.zilliz.milvustestv2.database;
 
+import com.google.common.collect.Lists;
 import com.zilliz.milvustestv2.common.BaseTest;
 import com.zilliz.milvustestv2.common.CommonData;
+import com.zilliz.milvustestv2.common.CommonFunction;
+import com.zilliz.milvustestv2.utils.MathUtil;
+import io.milvus.v2.common.ConsistencyLevel;
 import io.milvus.v2.common.DataType;
+import io.milvus.v2.service.collection.request.CreateCollectionReq;
+import io.milvus.v2.service.collection.request.DropCollectionReq;
+import io.milvus.v2.service.collection.response.ListCollectionsResp;
 import io.milvus.v2.service.database.request.CreateDatabaseReq;
 import io.milvus.v2.service.database.request.DropDatabaseReq;
 import io.milvus.v2.service.database.response.ListDatabasesResp;
+import io.milvus.v2.service.vector.request.QueryReq;
+import io.milvus.v2.service.vector.request.SearchReq;
+import io.milvus.v2.service.vector.request.data.BaseVector;
+import io.milvus.v2.service.vector.response.QueryResp;
+import io.milvus.v2.service.vector.response.SearchResp;
+import org.junit.platform.commons.util.StringUtils;
 import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.DataProvider;
 import org.testng.annotations.Test;
 
+import java.util.List;
+import java.util.Random;
+
 
 public class CreateDatabaseTest extends BaseTest {
 
     @DataProvider(name = "differentCollection")
     public Object[][] providerVectorType() {
         return new Object[][]{
-                { DataType.FloatVector},
-                { DataType.BinaryVector},
-                { DataType.Float16Vector},
-                { DataType.BFloat16Vector},
-                { DataType.SparseFloatVector},
+                {DataType.FloatVector},
+                {DataType.BinaryVector},
+                {DataType.Float16Vector},
+                {DataType.BFloat16Vector},
+                {DataType.SparseFloatVector},
         };
     }
 
     @AfterClass(alwaysRun = true)
-    public void cleanTestData(){
+    public void cleanTestData() {
+        try {
+            milvusClientV2.useDatabase(CommonData.databaseName);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+        ListCollectionsResp listCollectionsResp = milvusClientV2.listCollections();
+        for (String collectionName : listCollectionsResp.getCollectionNames()) {
+            milvusClientV2.dropCollection(DropCollectionReq.builder().collectionName(collectionName).build());
+        }
         milvusClientV2.dropDatabase(DropDatabaseReq.builder().databaseName(CommonData.databaseName).build());
     }
 
-    @Test(description = "Create database",groups = {"Smoke"})
-    public void createDatabase(){
+    @Test(description = "Create database", groups = {"Smoke"})
+    public void createDatabase() {
         milvusClientV2.createDatabase(CreateDatabaseReq.builder()
                 .databaseName(CommonData.databaseName).build());
         ListDatabasesResp listDatabasesResp = milvusClientV2.listDatabases();
         Assert.assertTrue(listDatabasesResp.getDatabaseNames().contains(CommonData.databaseName));
     }
 
-    @Test(description = "Create database with same name repeatedly ",groups = {"Smoke"},dependsOnMethods = {"createDatabase"})
-    public void createDatabaseRepeatedly(){
+    @Test(description = "Create database with same name repeatedly ", groups = {"Smoke"}, dependsOnMethods = {"createDatabase"})
+    public void createDatabaseRepeatedly() {
         try {
             milvusClientV2.createDatabase(CreateDatabaseReq.builder()
                     .databaseName(CommonData.databaseName).build());
@@ -49,4 +74,112 @@ public class CreateDatabaseTest extends BaseTest {
 
 
     }
+
+    @Test(description = "Search in database", groups = {"Smoke"}, dependsOnMethods = {"createDatabase"})
+    public void searchInDatabase() {
+        String collectionName = "a" + MathUtil.getRandomString(10);
+        CreateCollectionReq.CollectionSchema collectionSchema = CommonFunction.providerCollectionSchema(CommonData.dim, DataType.FloatVector);
+        milvusClientV2.createCollection(CreateCollectionReq.builder().collectionSchema(collectionSchema)
+                .numShards(1)
+                .databaseName(CommonData.databaseName)
+                .collectionName(collectionName)
+                .build());
+        // use db
+        try {
+            milvusClientV2.useDatabase(CommonData.databaseName);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+        CommonFunction.createIndexAndInsertAndLoad(collectionName, DataType.FloatVector, true, CommonData.numberEntities);
+        List<BaseVector> data = CommonFunction.providerBaseVector(CommonData.nq, CommonData.dim, DataType.FloatVector);
+        SearchResp search = milvusClientV2.search(SearchReq.builder()
+                .collectionName(collectionName)
+                .consistencyLevel(ConsistencyLevel.STRONG)
+                .annsField(CommonData.fieldFloatVector)
+                .databaseName(CommonData.databaseName)
+                .data(data)
+                .topK(10)
+                .build());
+
+        Assert.assertEquals(search.getSearchResults().size(), CommonData.nq);
+        Assert.assertEquals(search.getSearchResults().get(0).size(), 10);
+
+
+        milvusClientV2.dropCollection(DropCollectionReq.builder().collectionName(collectionName).build());
+
+
+        SearchResp search2 = milvusClientV2.search(SearchReq.builder()
+                .collectionName(CommonData.defaultFloatVectorCollection)
+                .consistencyLevel(ConsistencyLevel.STRONG)
+                .annsField(CommonData.fieldFloatVector)
+                .databaseName("default")
+                .data(data)
+                .topK(10)
+                .build());
+        Assert.assertEquals(search2.getSearchResults().size(), CommonData.nq);
+        Assert.assertEquals(search2.getSearchResults().get(0).size(), 10);
+
+        // 不指定databaseName
+        try {
+            SearchResp search3 = milvusClientV2.search(SearchReq.builder()
+                    .collectionName(CommonData.defaultFloatVectorCollection)
+                    .consistencyLevel(ConsistencyLevel.STRONG)
+                    .annsField(CommonData.fieldFloatVector)
+                    .data(data)
+                    .topK(10)
+                    .build());
+        } catch (Exception e) {
+            Assert.assertTrue(e.getMessage().contains("collection not found"));
+        }
+
+    }
+
+    @Test(description = "Query in database", groups = {"Smoke"}, dependsOnMethods = {"createDatabase"})
+    public void queryInDatabase() {
+        String collectionName = "a" + MathUtil.getRandomString(10);
+        CreateCollectionReq.CollectionSchema collectionSchema = CommonFunction.providerCollectionSchema(CommonData.dim, DataType.FloatVector);
+        milvusClientV2.createCollection(CreateCollectionReq.builder().collectionSchema(collectionSchema)
+                .numShards(1)
+                .databaseName(CommonData.databaseName)
+                .collectionName(collectionName)
+                .build());
+        // use database
+        try {
+            milvusClientV2.useDatabase(CommonData.databaseName);
+        } catch (InterruptedException e) {
+            throw new RuntimeException(e);
+        }
+        CommonFunction.createIndexAndInsertAndLoad(collectionName, DataType.FloatVector, true, CommonData.numberEntities);
+        QueryResp query = milvusClientV2.query(QueryReq.builder()
+                .collectionName(collectionName)
+                .consistencyLevel(ConsistencyLevel.STRONG)
+                .outputFields(Lists.newArrayList("*"))
+                .ids(Lists.newArrayList(1, 2, 3, 4))
+                .databaseName(CommonData.databaseName)
+                .build());
+        Assert.assertEquals(query.getQueryResults().size(), 4);
+        milvusClientV2.dropCollection(DropCollectionReq.builder().collectionName(collectionName).build());
+
+        QueryResp query2 = milvusClientV2.query(QueryReq.builder()
+                .collectionName(CommonData.defaultFloatVectorCollection)
+                .consistencyLevel(ConsistencyLevel.STRONG)
+                .outputFields(Lists.newArrayList("*"))
+                .ids(Lists.newArrayList(1, 2, 3, 4))
+                .databaseName("default")
+                .build());
+        Assert.assertEquals(query2.getQueryResults().size(), 4);
+
+        // 不指定databaseName
+        try {
+            QueryResp query3 = milvusClientV2.query(QueryReq.builder()
+                    .collectionName(CommonData.defaultFloatVectorCollection)
+                    .consistencyLevel(ConsistencyLevel.STRONG)
+                    .outputFields(Lists.newArrayList("*"))
+                    .ids(Lists.newArrayList(1, 2, 3, 4))
+                    .build());
+        } catch (Exception e) {
+            Assert.assertTrue(e.getMessage().contains("can't find collection"));
+        }
+    }
+
 }

+ 224 - 4
tests/milvustestv2/src/test/java/com/zilliz/milvustestv2/index/CreateIndexTest.java

@@ -6,22 +6,27 @@ import com.zilliz.milvustestv2.common.BaseTest;
 import com.zilliz.milvustestv2.common.CommonData;
 import com.zilliz.milvustestv2.common.CommonFunction;
 import com.zilliz.milvustestv2.params.FieldParam;
+import io.milvus.v2.common.ConsistencyLevel;
 import io.milvus.v2.common.DataType;
 import io.milvus.v2.common.IndexParam;
 import io.milvus.v2.service.collection.request.DropCollectionReq;
 import io.milvus.v2.service.collection.request.LoadCollectionReq;
 import io.milvus.v2.service.collection.request.ReleaseCollectionReq;
 import io.milvus.v2.service.index.request.CreateIndexReq;
+import io.milvus.v2.service.index.request.DescribeIndexReq;
+import io.milvus.v2.service.index.response.DescribeIndexResp;
 import io.milvus.v2.service.vector.request.InsertReq;
+import io.milvus.v2.service.vector.request.SearchReq;
+import io.milvus.v2.service.vector.request.data.BaseVector;
+import io.milvus.v2.service.vector.response.SearchResp;
+import org.testng.Assert;
 import org.testng.annotations.AfterClass;
 import org.testng.annotations.BeforeClass;
 import org.testng.annotations.Test;
 import lombok.extern.slf4j.Slf4j;
 import org.testng.annotations.*;
 
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
+import java.util.*;
 
 /**
  * @Author yongpeng.li
@@ -31,6 +36,10 @@ import java.util.List;
 public class CreateIndexTest extends BaseTest {
     String newCollectionName;
 
+    String dynamicCollectionName;
+
+    int topK=100;
+
     @DataProvider(name = "multiScalar")
     public Object[][] providerScalarIndex() {
         return new Object[][]{
@@ -73,16 +82,24 @@ public class CreateIndexTest extends BaseTest {
         };
     }
 
+
+
     @BeforeClass(alwaysRun = true)
     public void providerCollection() {
         newCollectionName = CommonFunction.createNewCollection(CommonData.dim, null, DataType.FloatVector);
-        List<JsonObject> jsonObjects = CommonFunction.generateDefaultData(0, CommonData.numberEntities * 10, CommonData.dim, DataType.FloatVector);
+        List<JsonObject> jsonObjects = CommonFunction.generateDefaultData(0, CommonData.numberEntities, CommonData.dim, DataType.FloatVector);
         milvusClientV2.insert(InsertReq.builder().collectionName(newCollectionName).data(jsonObjects).build());
+
+        // 创建dynamicCollectionName
+        dynamicCollectionName=CommonFunction.createNewCollectionWithDynamic(CommonData.dim,null,DataType.FloatVector);
+        List<JsonObject> jsonObjectsDynamic =CommonFunction.generateDefaultDataWithDynamic(0,CommonData.numberEntities, CommonData.dim, DataType.FloatVector);
+        milvusClientV2.insert(InsertReq.builder().collectionName(dynamicCollectionName).data(jsonObjectsDynamic).build());
     }
 
     @AfterClass(alwaysRun = true)
     public void cleanTestData() {
         milvusClientV2.dropCollection(DropCollectionReq.builder().collectionName(newCollectionName).build());
+        milvusClientV2.dropCollection(DropCollectionReq.builder().collectionName(dynamicCollectionName).build());
     }
 
     @Test(description = "Create vector index", groups = {"Smoke"})
@@ -100,6 +117,22 @@ public class CreateIndexTest extends BaseTest {
         milvusClientV2.loadCollection(LoadCollectionReq.builder().collectionName(newCollectionName).build());
 
     }
+    @Test(description = "Create vector index with dynamic", groups = {"Smoke"})
+    public void createVectorIndexWithDynamic() {
+        IndexParam indexParam = IndexParam.builder()
+                .fieldName(CommonData.fieldFloatVector)
+                .indexType(IndexParam.IndexType.AUTOINDEX)
+                .extraParams(CommonFunction.provideExtraParam(IndexParam.IndexType.AUTOINDEX))
+                .metricType(IndexParam.MetricType.L2)
+                .build();
+        milvusClientV2.createIndex(CreateIndexReq.builder()
+                .collectionName(dynamicCollectionName)
+                .indexParams(Collections.singletonList(indexParam))
+                .build());
+        milvusClientV2.loadCollection(LoadCollectionReq.builder().collectionName(dynamicCollectionName).build());
+
+    }
+
 
     @Test(description = "Create scalar index", groups = {"Smoke"}, dependsOnMethods = {"createVectorIndex"})
     public void createScalarIndex() {
@@ -157,4 +190,191 @@ public class CreateIndexTest extends BaseTest {
         milvusClientV2.releaseCollection(ReleaseCollectionReq.builder().collectionName(newCollectionName).build());
         CommonFunction.dropScalarCommonIndex(newCollectionName, FieldParamList);
     }
+
+    @DataProvider(name = "jsonPathIndex")
+    public Object[][] providerJsonPathIndex() {
+        return new Object[][]{
+                {"json_index_0", DataType.Double, CommonData.fieldJson, CommonData.fieldJson + "[\"" + CommonData.fieldInt64 + "\"] in [1,2,3]", 3},
+                {"json_index_1", DataType.Double, CommonData.fieldJson + "['" + CommonData.fieldFloat + "']", CommonData.fieldJson + "[\"" + CommonData.fieldFloat + "\"] < 5", 5},
+                {"json_index_2", DataType.Double, CommonData.fieldJson + "['" + CommonData.fieldArray + "'][0]", CommonData.fieldJson + "['" + CommonData.fieldArray + "'][0] == 1", 1},
+                {"json_index_3",DataType.Bool,CommonData.fieldJson + "['" + CommonData.fieldBool + "']", CommonData.fieldJson + "[\"" + CommonData.fieldBool + "\"] == true", topK },
+                {"json_index_4",DataType.VarChar,CommonData.fieldJson+"['"+CommonData.fieldVarchar+"']",CommonData.fieldJson+"[\""+CommonData.fieldVarchar+"\"] == \"Str1\"",1},
+        };
+    }
+
+    @DataProvider(name = "jsonPathIndexDynamic")
+    public Object[][] providerJsonPathIndexDynamic() {
+        return new Object[][]{
+                {"json_index_0", DataType.Double, CommonData.fieldDynamic, CommonData.fieldDynamic + "[\"" + CommonData.fieldInt64 + "\"] in [1,2,3]", 3},
+                {"json_index_1", DataType.Double, CommonData.fieldDynamic + "['" + CommonData.fieldFloat + "']", CommonData.fieldDynamic + "[\"" + CommonData.fieldFloat + "\"] < 5", 5},
+                {"json_index_2", DataType.Double, CommonData.fieldDynamic + "['" + CommonData.fieldArray + "'][0]", CommonData.fieldDynamic + "[\"" + CommonData.fieldArray + "\"][0] == 1", 1},
+                {"json_index_3",DataType.Bool,CommonData.fieldDynamic + "['" + CommonData.fieldBool + "']", CommonData.fieldDynamic + "[\"" + CommonData.fieldBool + "\"] == true", topK },
+                {"json_index_4",DataType.VarChar,CommonData.fieldDynamic+"['"+CommonData.fieldVarchar+"']",CommonData.fieldDynamic+"[\""+CommonData.fieldVarchar+"\"] == \"Str1\"",1},
+        };
+    }
+    @Test(description = "Create json path index", groups = {"Smoke"}, dependsOnMethods = {"createVectorIndex"}, dataProvider = "jsonPathIndex")
+    public void createJsonPathIndex(String indexName, DataType jsonCastType, String jsonPath, String filter, int except) {
+        milvusClientV2.releaseCollection(ReleaseCollectionReq.builder().collectionName(newCollectionName).build());
+        Map<String, Object> params = new HashMap<>();
+        params.put("json_cast_type", jsonCastType);
+        params.put("json_path", jsonPath);
+        IndexParam indexParam = IndexParam.builder()
+                .fieldName(CommonData.fieldJson)
+                .indexType(IndexParam.IndexType.INVERTED)
+                .indexName(indexName)
+                .extraParams(params)
+                .build();
+        System.out.println(indexParam.toString());
+        milvusClientV2.createIndex(CreateIndexReq.builder()
+                .collectionName(newCollectionName)
+                .indexParams(Collections.singletonList(indexParam))
+                .build());
+        // describe index
+        DescribeIndexResp describeIndexResp = milvusClientV2.describeIndex(DescribeIndexReq.builder().collectionName(newCollectionName).indexName(indexName).build());
+        Assert.assertEquals(describeIndexResp.getIndexDescByIndexName(indexName).getIndexType(), IndexParam.IndexType.INVERTED);
+
+        milvusClientV2.loadCollection(LoadCollectionReq.builder()
+                .collectionName(newCollectionName)
+                .build());
+
+        List<BaseVector> data = CommonFunction.providerBaseVector(CommonData.nq, CommonData.dim, DataType.FloatVector);
+        SearchResp search = milvusClientV2.search(SearchReq.builder()
+                .collectionName(newCollectionName)
+                .consistencyLevel(ConsistencyLevel.STRONG)
+                .annsField(CommonData.fieldFloatVector)
+                .filter(filter)
+                .data(data)
+                .topK(topK)
+                .build());
+        Assert.assertEquals(search.getSearchResults().get(0).size(), except);
+        System.out.println(search.getSearchResults().get(0).get(0).toString());
+    }
+
+    @Test(description = "Create json path index with dynamic field", groups = {"Smoke"}, dependsOnMethods = {"createVectorIndexWithDynamic"}, dataProvider = "jsonPathIndexDynamic")
+    public void createJsonPathIndexWithDynamic(String indexName, DataType jsonCastType, String jsonPath, String filter, int except) {
+        milvusClientV2.releaseCollection(ReleaseCollectionReq.builder().collectionName(dynamicCollectionName).build());
+
+        Map<String, Object> params = new HashMap<>();
+        params.put("json_cast_type", jsonCastType);
+        params.put("json_path", jsonPath);
+        IndexParam indexParam = IndexParam.builder()
+                .fieldName(CommonData.fieldDynamic)
+                .indexType(IndexParam.IndexType.INVERTED)
+                .indexName(indexName)
+                .extraParams(params)
+                .build();
+        System.out.println(indexParam.toString());
+        milvusClientV2.createIndex(CreateIndexReq.builder()
+                .collectionName(dynamicCollectionName)
+                .indexParams(Collections.singletonList(indexParam))
+                .build());
+        // describe index
+        DescribeIndexResp describeIndexResp = milvusClientV2.describeIndex(DescribeIndexReq.builder().collectionName(dynamicCollectionName).indexName(indexName).build());
+        Assert.assertEquals(describeIndexResp.getIndexDescByIndexName(indexName).getIndexType(), IndexParam.IndexType.INVERTED);
+
+        milvusClientV2.loadCollection(LoadCollectionReq.builder()
+                .collectionName(dynamicCollectionName)
+                .build());
+
+        List<BaseVector> data = CommonFunction.providerBaseVector(CommonData.nq, CommonData.dim, DataType.FloatVector);
+        SearchResp search = milvusClientV2.search(SearchReq.builder()
+                .collectionName(dynamicCollectionName)
+                .consistencyLevel(ConsistencyLevel.STRONG)
+                .annsField(CommonData.fieldFloatVector)
+                .filter(filter)
+                .data(data)
+                .topK(topK)
+                .build());
+        Assert.assertEquals(search.getSearchResults().get(0).size(), except);
+    }
+
+    @Test(description = "Dynamic collection create json path index with not existed field ",groups = {"L1"})
+    public void dynamicCollectionCreateJsonPathIndexWithNotExistedField(){
+        String newCollectionWithDynamic = CommonFunction.createNewCollectionWithDynamic(CommonData.dim, null, DataType.FloatVector);
+        IndexParam indexParam = IndexParam.builder()
+                .fieldName(CommonData.fieldFloatVector)
+                .indexType(IndexParam.IndexType.AUTOINDEX)
+                .extraParams(CommonFunction.provideExtraParam(IndexParam.IndexType.AUTOINDEX))
+                .metricType(IndexParam.MetricType.L2)
+                .build();
+        milvusClientV2.createIndex(CreateIndexReq.builder()
+                .collectionName(newCollectionWithDynamic)
+                .indexParams(Collections.singletonList(indexParam))
+                .build());
+        // create json index
+        Map<String, Object> params = new HashMap<>();
+        params.put("json_cast_type", DataType.Double);
+        params.put("json_path", CommonData.fieldDynamicNotExist);
+        IndexParam indexParam2 = IndexParam.builder()
+                .fieldName(CommonData.fieldDynamicNotExist)
+                .indexType(IndexParam.IndexType.INVERTED)
+                .indexName("not_existed_index")
+                .extraParams(params)
+                .build();
+        milvusClientV2.createIndex(CreateIndexReq.builder()
+                .collectionName(newCollectionWithDynamic)
+                .indexParams(Collections.singletonList(indexParam2))
+                .build());
+
+        // describe index
+        DescribeIndexResp describeIndexResp = milvusClientV2.describeIndex(DescribeIndexReq.builder().collectionName(newCollectionWithDynamic).indexName("not_existed_index").build());
+        System.out.println("describeIndexResp: "+describeIndexResp.toString());
+    }
+
+    @Test(description = "Create json path index with not existed field ",groups = {"L1"})
+    public void createJsonPathIndexWithNotExistedField(){
+        String newCollection = CommonFunction.createNewCollection(CommonData.dim, null, DataType.FloatVector);
+        IndexParam indexParam = IndexParam.builder()
+                .fieldName(CommonData.fieldFloatVector)
+                .indexType(IndexParam.IndexType.AUTOINDEX)
+                .extraParams(CommonFunction.provideExtraParam(IndexParam.IndexType.AUTOINDEX))
+                .metricType(IndexParam.MetricType.L2)
+                .build();
+        milvusClientV2.createIndex(CreateIndexReq.builder()
+                .collectionName(newCollection)
+                .indexParams(Collections.singletonList(indexParam))
+                .build());
+        // create json index
+        Map<String, Object> params = new HashMap<>();
+        params.put("json_cast_type", DataType.Double);
+        params.put("json_path", CommonData.fieldDynamicNotExist);
+        IndexParam indexParam2 = IndexParam.builder()
+                .fieldName(CommonData.fieldDynamicNotExist)
+                .indexType(IndexParam.IndexType.INVERTED)
+                .indexName("not_existed_index")
+                .extraParams(params)
+                .build();
+        try {
+            milvusClientV2.createIndex(CreateIndexReq.builder()
+                    .collectionName(newCollection)
+                    .indexParams(Collections.singletonList(indexParam2))
+                    .build());
+        } catch (Exception e) {
+            Assert.assertTrue(e.getMessage().contains("cannot create index on non-exist field"));
+        }
+
+    }
+
+    @Test(description = "Create json path index repeatedly",groups = {"L1"},dependsOnMethods = {"createVectorIndex","createJsonPathIndex"})
+    public void createJsonPathIndexRepeatedly(){
+        milvusClientV2.releaseCollection(ReleaseCollectionReq.builder().collectionName(newCollectionName).build());
+        Map<String, Object> params = new HashMap<>();
+        params.put("json_cast_type", DataType.Double);
+        params.put("json_path", CommonData.fieldJson);
+        IndexParam indexParam = IndexParam.builder()
+                .fieldName(CommonData.fieldJson)
+                .indexType(IndexParam.IndexType.INVERTED)
+                .indexName("indexName_repeat")
+                .extraParams(params)
+                .build();
+        try {
+            milvusClientV2.createIndex(CreateIndexReq.builder()
+                    .collectionName(newCollectionName)
+                    .indexParams(Collections.singletonList(indexParam))
+                    .build());
+        } catch (Exception e) {
+            Assert.assertTrue(e.getMessage().contains("creating multiple indexes on same field is not supported"));
+        }
+    }
+
 }