From 64e42bf8ee7dd6ce0b6a789c45c5afc031aa987b Mon Sep 17 00:00:00 2001 From: yongpengli-z Date: Tue, 23 Apr 2024 11:45:25 +0800 Subject: [PATCH] add or modify testcases for 2.4 (#875) (#876) Signed-off-by: yongpengli-z --- tests/milvustest/pom.xml | 10 +- .../milvustest/common/BaseCloudTest.java | 6 +- .../zilliz/milvustest/common/CommonData.java | 5 + .../milvustest/common/CommonFunction.java | 358 +- .../com/zilliz/milvustest/util/MathUtil.java | 37 + .../zilliz/milvustest/bulk/BulkWriteTest.java | 6 +- .../milvustest/bulkimport/BulkImportTest.java | 2 +- .../collection/CreateCollectionTest.java | 160 + .../compaction/ManualCompactionTest.java | 2 +- .../milvustest/database/DatabaseTest.java | 6 +- .../milvustest/index/CreateIndexTest.java | 4 + .../milvustest/index/IndexLoadTest.java | 4 +- .../zilliz/milvustest/insert/DeleteTest.java | 2 +- .../zilliz/milvustest/insert/InsertTest.java | 65 + .../zilliz/milvustest/insert/UpsertTest.java | 11 +- .../milvustest/mmap/AlterCollectionTest.java | 250 + .../milvustest/mmap/AlterIndexTest.java | 250 + .../query/MultipleArraysDataFactory.java | 64 + .../milvustest/query/QueryIteratorTest.java | 119 + .../zilliz/milvustest/query/QueryTest.java | 134 +- .../milvustest/search/RangeSearchTest.java | 10 +- .../milvustest/search/SearchIteratorTest.java | 201 + .../zilliz/milvustest/search/SearchTest.java | 4208 +++++++++-------- .../segment/GetQuerySegmentInfoTest.java | 2 +- 24 files changed, 3964 insertions(+), 1952 deletions(-) create mode 100644 tests/milvustest/src/test/java/com/zilliz/milvustest/mmap/AlterCollectionTest.java create mode 100644 tests/milvustest/src/test/java/com/zilliz/milvustest/mmap/AlterIndexTest.java create mode 100644 tests/milvustest/src/test/java/com/zilliz/milvustest/query/MultipleArraysDataFactory.java create mode 100644 tests/milvustest/src/test/java/com/zilliz/milvustest/query/QueryIteratorTest.java create mode 100644 tests/milvustest/src/test/java/com/zilliz/milvustest/search/SearchIteratorTest.java diff --git a/tests/milvustest/pom.xml b/tests/milvustest/pom.xml index e0b97cf3b..5944f8e93 100644 --- a/tests/milvustest/pom.xml +++ b/tests/milvustest/pom.xml @@ -89,7 +89,7 @@ com.google.protobuf protobuf-java - 3.19.6 + 3.24.0 @@ -106,10 +106,10 @@ org.slf4j slf4j-api - - org.apache.logging.log4j - log4j-slf4j-impl - + + + + org.apache.logging.log4j log4j-api diff --git a/tests/milvustest/src/main/java/com/zilliz/milvustest/common/BaseCloudTest.java b/tests/milvustest/src/main/java/com/zilliz/milvustest/common/BaseCloudTest.java index 9a5d63726..8c7b1c485 100644 --- a/tests/milvustest/src/main/java/com/zilliz/milvustest/common/BaseCloudTest.java +++ b/tests/milvustest/src/main/java/com/zilliz/milvustest/common/BaseCloudTest.java @@ -29,7 +29,7 @@ @SpringBootTest(classes = MilvustestApplication.class) @WebAppConfiguration public class BaseCloudTest extends AbstractTestNGSpringContextTests { - public static final Logger logger= LoggerFactory.getLogger(BaseCloudTest.class); +// public static final Logger logger= LoggerFactory.getLogger(BaseCloudTest.class); public static final MilvusServiceClient milvusCloudClient = new MilvusServiceClient( ConnectParam.newBuilder() @@ -47,7 +47,7 @@ public class BaseCloudTest extends AbstractTestNGSpringContextTests { .withSecure(true) .build()); - @BeforeSuite(alwaysRun = true) +// @BeforeSuite(alwaysRun = true) public void initCollection() { logger.info( "**************************************************BeforeSuit**********************"); @@ -67,7 +67,7 @@ public void initCollection() { milvusCloudClient.createDatabase(CreateDatabaseParam.newBuilder().withDatabaseName(CommonData.databaseName1).build()); } - @AfterSuite(alwaysRun = true) +// @AfterSuite(alwaysRun = true) public void cleanTestData() { logger.info( "**************************************************AfterSuit**********************"); diff --git a/tests/milvustest/src/main/java/com/zilliz/milvustest/common/CommonData.java b/tests/milvustest/src/main/java/com/zilliz/milvustest/common/CommonData.java index 9e5943619..b5aabaf84 100644 --- a/tests/milvustest/src/main/java/com/zilliz/milvustest/common/CommonData.java +++ b/tests/milvustest/src/main/java/com/zilliz/milvustest/common/CommonData.java @@ -16,6 +16,9 @@ public class CommonData { public static String defaultVectorField = "book_intro"; public static String defaultPartitionField="book_name"; public static String defaultBinaryVectorField = "BinaryVectorFieldAutoTest"; + public static String defaultFloat16VectorField = "Float16VectorField"; + public static String defaultBF16VectorField = "BF16VectorField"; + public static String defaultSparseVectorField = "SparseFloatVectorField"; public static String defaultIndex = "FloatVectorIndex"; public static String defaultBinaryIndex = "BinaryVectorIndex"; @@ -33,5 +36,7 @@ public class CommonData { public static String defaultRoleName2 = "roleTest2"; public static String databaseName1="db1"; public static String databaseName2="db2"; + + public static int dim=128; } diff --git a/tests/milvustest/src/main/java/com/zilliz/milvustest/common/CommonFunction.java b/tests/milvustest/src/main/java/com/zilliz/milvustest/common/CommonFunction.java index 60d44d2fe..1648a3bd7 100644 --- a/tests/milvustest/src/main/java/com/zilliz/milvustest/common/CommonFunction.java +++ b/tests/milvustest/src/main/java/com/zilliz/milvustest/common/CommonFunction.java @@ -15,11 +15,10 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.stereotype.Component; + + import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Random; +import java.util.*; import static com.zilliz.milvustest.common.BaseTest.milvusClient; @@ -161,6 +160,94 @@ public static String createBinaryCollection() { return collectionName; } + public static String createFloat16Collection(){ + String collectionName = "Collection_" + MathUtil.getRandomString(10); + FieldType fieldType1 = + FieldType.newBuilder() + .withName("book_id") + .withDataType(DataType.Int64) + .withPrimaryKey(true) + .withAutoID(false) + .build(); + FieldType fieldType2 = + FieldType.newBuilder().withName("word_count").withDataType(DataType.Int64).build(); + FieldType fieldType3 = + FieldType.newBuilder() + .withName(CommonData.defaultFloat16VectorField) + .withDataType(DataType.Float16Vector) + .withDimension(CommonData.dim) + .build(); + CollectionSchemaParam collectionSchemaParam = CollectionSchemaParam.newBuilder().addFieldType(fieldType1).addFieldType(fieldType2).addFieldType(fieldType3).build(); + CreateCollectionParam createCollectionReq = + CreateCollectionParam.newBuilder() + .withCollectionName(collectionName) + .withDescription("Test" + collectionName + "search") + .withShardsNum(2) + .withSchema(collectionSchemaParam) + .build(); + R collection = BaseTest.milvusClient.createCollection(createCollectionReq); + logger.info("create collection:" + collectionName); + return collectionName; + } + public static String createBf16Collection(){ + String collectionName = "Collection_" + MathUtil.getRandomString(10); + FieldType fieldType1 = + FieldType.newBuilder() + .withName("book_id") + .withDataType(DataType.Int64) + .withPrimaryKey(true) + .withAutoID(false) + .build(); + FieldType fieldType2 = + FieldType.newBuilder().withName("word_count").withDataType(DataType.Int64).build(); + FieldType fieldType3 = + FieldType.newBuilder() + .withName(CommonData.defaultBF16VectorField) + .withDataType(DataType.BFloat16Vector) + .withDimension(CommonData.dim) + .build(); + CollectionSchemaParam collectionSchemaParam = CollectionSchemaParam.newBuilder().addFieldType(fieldType1).addFieldType(fieldType2).addFieldType(fieldType3).build(); + CreateCollectionParam createCollectionReq = + CreateCollectionParam.newBuilder() + .withCollectionName(collectionName) + .withDescription("Test" + collectionName + "search") + .withShardsNum(2) + .withSchema(collectionSchemaParam) + .build(); + R collection = BaseTest.milvusClient.createCollection(createCollectionReq); + logger.info("create collection:" + collectionName); + return collectionName; + } + + public static String createSparseFloatVectorCollection(){ + String collectionName = "Collection_" + MathUtil.getRandomString(10); + FieldType fieldType1 = + FieldType.newBuilder() + .withName("book_id") + .withDataType(DataType.Int64) + .withPrimaryKey(true) + .withAutoID(false) + .build(); + FieldType fieldType2 = + FieldType.newBuilder().withName("word_count").withDataType(DataType.Int64).build(); + FieldType fieldType3 = + FieldType.newBuilder() + .withName(CommonData.defaultSparseVectorField) + .withDataType(DataType.SparseFloatVector) + .build(); + CollectionSchemaParam collectionSchemaParam = CollectionSchemaParam.newBuilder().addFieldType(fieldType1).addFieldType(fieldType2).addFieldType(fieldType3).build(); + CreateCollectionParam createCollectionReq = + CreateCollectionParam.newBuilder() + .withCollectionName(collectionName) + .withDescription("Test" + collectionName + "search") + .withShardsNum(2) + .withSchema(collectionSchemaParam) + .build(); + R collection = BaseTest.milvusClient.createCollection(createCollectionReq); + logger.info("create collection:" + collectionName); + return collectionName; + } + // String pk,float vector collection public static String createStringPKCollection() { String collectionName = "Collection_" + MathUtil.getRandomString(10); @@ -279,6 +366,68 @@ public static MilvusEntity createCollectionWithAll() { return milvusEntity; } + public static String createMultiVectorCollection(){ + String collectionName = "Collection_" + MathUtil.getRandomString(10); + FieldType fieldType1 = + FieldType.newBuilder() + .withName("book_id") + .withDataType(DataType.Int64) + .withPrimaryKey(true) + .withAutoID(false) + .build(); + FieldType fieldType2 = + FieldType.newBuilder().withName("word_count").withDataType(DataType.Int64).build(); + FieldType fieldType3 = + FieldType.newBuilder() + .withName(CommonData.defaultVectorField) + .withDataType(DataType.FloatVector) + .withDimension(CommonData.dim) + .build(); + FieldType fieldType4 = + FieldType.newBuilder() + .withName(CommonData.defaultBinaryVectorField) + .withDataType(DataType.BinaryVector) + .withDimension(CommonData.dim) + .build(); + FieldType fieldType5 = + FieldType.newBuilder() + .withName(CommonData.defaultSparseVectorField) + .withDataType(DataType.SparseFloatVector) + .build(); + FieldType fieldType6 = + FieldType.newBuilder() + .withName(CommonData.defaultFloat16VectorField) + .withDataType(DataType.Float16Vector) + .withDimension(CommonData.dim) + .build(); + FieldType fieldType7 = + FieldType.newBuilder() + .withName(CommonData.defaultBF16VectorField) + .withDataType(DataType.BFloat16Vector) + .withDimension(CommonData.dim) + .build(); + CollectionSchemaParam collectionSchemaParam = CollectionSchemaParam.newBuilder() + .addFieldType(fieldType1) + .addFieldType(fieldType2) + .addFieldType(fieldType3) + .addFieldType(fieldType4) + .addFieldType(fieldType5) + .addFieldType(fieldType6) +// .addFieldType(fieldType7) + .build(); + CreateCollectionParam createCollectionReq = + CreateCollectionParam.newBuilder() + .withCollectionName(collectionName) + .withDescription("Test" + collectionName + "search") + .withShardsNum(2) + .withSchema(collectionSchemaParam) + .build(); + R collection = BaseTest.milvusClient.createCollection(createCollectionReq); + System.out.println("create c:"+collection); + logger.info("create multi vector collection:" + collectionName); + return collectionName; + } + public static List generateData(int num) { Random ran = new Random(); List book_id_array = new ArrayList<>(); @@ -286,7 +435,7 @@ public static List generateData(int num) { List> book_intro_array = new ArrayList<>(); for (long i = 0L; i < num; ++i) { book_id_array.add(i); - word_count_array.add(i + 10000); + word_count_array.add(1L); List vector = new ArrayList<>(); for (int k = 0; k < 128; ++k) { vector.add(ran.nextFloat()); @@ -300,6 +449,129 @@ public static List generateData(int num) { // logger.info("generateTestData"+ JacksonUtil.serialize(fields)); return fields; } + + public static SortedMap generateSparseVector() { + Random ran = new Random(); + SortedMap sparse = new TreeMap<>(); + int dim = ran.nextInt(CommonData.dim) + 1; + for (int i = 0; i < dim; ++i) { + sparse.put((long)ran.nextInt(1000000), ran.nextFloat()); + } + return sparse; + } + public static List generateDataWithSparseFloatVector(int num) { + Random ran = new Random(); + List book_id_array = new ArrayList<>(); + List word_count_array = new ArrayList<>(); + List> book_intro_array = new ArrayList<>(); + for (long i = 0L; i < num; ++i) { + book_id_array.add(i); + word_count_array.add(1L); + SortedMap sparse = generateSparseVector(); + book_intro_array.add(sparse); + } + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_id", book_id_array)); + fields.add(new InsertParam.Field("word_count", word_count_array)); + fields.add(new InsertParam.Field(CommonData.defaultSparseVectorField, book_intro_array)); + return fields; + } + + public static List generateDataWithMultiVector(int num) { + Random ran = new Random(); + List book_id_array = new ArrayList<>(); + List word_count_array = new ArrayList<>(); + + List> sparseVectorList = new ArrayList<>(); + for (long i = 0L; i < num; ++i) { + book_id_array.add(i); + word_count_array.add(1L); + SortedMap sparse = generateSparseVector(); + sparseVectorList.add(sparse); + } + List> floatVector = generateFloatVectors(num,CommonData.dim); + List binaryVectorList = generateBinaryVectors(num, CommonData.dim); + List float16VectorList = generateFloat16Vectors(CommonData.dim,num); + List bf16VectorList = generateBF16Vectors(CommonData.dim, num); + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_id", book_id_array)); + fields.add(new InsertParam.Field("word_count", word_count_array)); + fields.add(new InsertParam.Field(CommonData.defaultVectorField, floatVector)); + fields.add(new InsertParam.Field(CommonData.defaultSparseVectorField, sparseVectorList)); + fields.add(new InsertParam.Field(CommonData.defaultBinaryVectorField, binaryVectorList)); + fields.add(new InsertParam.Field(CommonData.defaultFloat16VectorField,float16VectorList)); +// fields.add(new InsertParam.Field(CommonData.defaultBF16VectorField,bf16VectorList)); + return fields; + } + public static List generateDataWithBF16Vector(int num) { + List book_id_array = new ArrayList<>(); + List word_count_array = new ArrayList<>(); + List book_intro_array = generateBF16Vectors(CommonData.dim, num); + for (long i = 0L; i < num; ++i) { + book_id_array.add(i); + word_count_array.add(1L); + } + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_id", book_id_array)); + fields.add(new InsertParam.Field("word_count", word_count_array)); + fields.add(new InsertParam.Field(CommonData.defaultBF16VectorField, book_intro_array)); + // logger.info("generateTestData"+ JacksonUtil.serialize(fields)); + return fields; + } + + public static List generateDataWithFloat16Vector(int num) { + Random ran = new Random(); + List book_id_array = new ArrayList<>(); + List word_count_array = new ArrayList<>(); + List book_intro_array = generateFloat16Vectors(CommonData.dim, num); + for (long i = 0L; i < num; ++i) { + book_id_array.add(i); + word_count_array.add(1L); + } + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_id", book_id_array)); + fields.add(new InsertParam.Field("word_count", word_count_array)); + fields.add(new InsertParam.Field(CommonData.defaultFloat16VectorField, book_intro_array)); + // logger.info("generateTestData"+ JacksonUtil.serialize(fields)); + return fields; + } + + public static List generateFloat16Vectors(int VECTOR_DIM,int count) { + Random ran = new Random(); + List vectors = new ArrayList<>(); + int byteCount = VECTOR_DIM*2; + for (int n = 0; n < count; ++n) { + ByteBuffer vector = ByteBuffer.allocate(byteCount); + for (int i = 0; i < VECTOR_DIM; ++i) { + short halfFloatValue = MathUtil.floatToFloat16(count+0.1f); + ByteBuffer buffer = ByteBuffer.allocate(2); + buffer.putShort(halfFloatValue); + buffer.flip(); + vector.put(buffer.get(0)); + vector.put(buffer.get(1)); + } + vectors.add(vector); + } + + return vectors; + } + public static List generateBF16Vectors(int VECTOR_DIM,int count) { + List vectors = new ArrayList<>(); + int byteCount = VECTOR_DIM*2; + for (int n = 0; n < count; ++n) { + ByteBuffer vector = ByteBuffer.allocate(byteCount); + for (int i = 0; i < VECTOR_DIM; ++i) { + short halfFloatValue = MathUtil.floatToBF16(count+0.1f); + ByteBuffer buffer = ByteBuffer.allocate(2); + buffer.putShort(halfFloatValue); + buffer.flip(); + vector.put(buffer.get(0)); + vector.put(buffer.get(1)); + } + vectors.add(vector); + } + return vectors; + } public static List generateDataWithPartitionKey(int num) { Random ran = new Random(); List book_id_array = new ArrayList<>(); @@ -472,7 +744,7 @@ public static String provideExtraParam(IndexType indexType) { extraParam = "{}"; break; case IVF_FLAT: - extraParam = "{\"nlist\":128}"; + extraParam = "{\"nlist\":32,\"nprobe\":32}"; break; case IVF_SQ8: extraParam = "{\"nlist\":128}"; @@ -507,6 +779,10 @@ public static String provideExtraParam(IndexType indexType) { case GPU_IVF_PQ: extraParam="{\"nlist\": 64, \"m\": 16, \"nbits\": 8}"; break; + case SPARSE_INVERTED_INDEX: + case SPARSE_WAND: + extraParam="{\"drop_ratio_search\":0.2}"; + break; default: extraParam = "{\"nlist\":128}"; break; @@ -792,14 +1068,31 @@ public static List generateVarcharPKDataWithDynamicFiledRow(int num) jsonList.add(row); } return jsonList; + } + public static void createIndexWithoutLoad(String collection, IndexType indexType, MetricType metricType, String fieldName){ + milvusClient.flush(FlushParam.newBuilder().withCollectionNames(Lists.newArrayList(collection)).build()); + R rpcStatusR = + milvusClient.createIndex( + CreateIndexParam.newBuilder() + .withCollectionName(collection) + .withFieldName(fieldName) + .withMetricType(metricType) + .withIndexType(indexType) + .withIndexName("idx_"+fieldName) + .withExtraParam(CommonFunction.provideExtraParam(indexType)) + .withSyncMode(Boolean.FALSE) + .build()); + + } public static void createIndexWithLoad(String collection, IndexType indexType, MetricType metricType, String fieldName){ + milvusClient.flush(FlushParam.newBuilder().withCollectionNames(Lists.newArrayList(collection)).withSyncFlush(true).build()); R rpcStatusR = milvusClient.createIndex( CreateIndexParam.newBuilder() .withCollectionName(collection) .withFieldName(fieldName) - .withIndexName(CommonData.defaultIndex) + .withIndexName("idx_"+fieldName) .withMetricType(metricType) .withIndexType(indexType) .withExtraParam(CommonFunction.provideExtraParam(indexType)) @@ -899,4 +1192,55 @@ public static CollectionSchemaParam provideJsonCollectionSchema(){ .addFieldType(fieldType5) .addFieldType(fieldType6).build(); } + + // 实现float到float16的转换 + private static short floatToFloat16(float value) { + int floatBits = Float.floatToIntBits(value); + int sign = (floatBits >> 16) & 0x8000; // 符号位 + int exponent = ((floatBits >> 23) & 0xFF) - 127 + 15; // 指数位 + int significand = floatBits & 0x7FFFFF; // 尾数位 + + if (exponent <= 0) { + if (exponent < -10) { + // 浮点数太小,直接转为0 + return (short) sign; + } + // 将尾数位向右移动 + significand = (significand | 0x800000) >> (1 - exponent); + // 考虑舍入 + if ((significand & 0x1000) == 0x1000) { + significand += 0x2000; + if ((significand & 0x800000) == 0x800000) { + significand = 0; + exponent++; + } + } + exponent = 0; + } else if (exponent == 0xFF - 127 + 15) { + if (significand == 0) { + // 正无穷大 + return (short) (sign | 0x7C00); + } else { + // NaN + significand >>= 13; + return (short) (sign | 0x7C00 | significand | (significand == 0 ? 1 : 0)); + } + } else { + // 正常情况下,只需要移动尾数位 + if ((significand & 0x1000) == 0x1000) { + significand += 0x2000; + if ((significand & 0x800000) == 0x800000) { + significand = 0; + exponent++; + } + } + if (exponent > 30) { + // 浮点数太大,转为正无穷大 + return (short) (sign | 0x7C00); + } + } + + return (short) (sign | (exponent << 10) | (significand >> 13)); + } + } diff --git a/tests/milvustest/src/main/java/com/zilliz/milvustest/util/MathUtil.java b/tests/milvustest/src/main/java/com/zilliz/milvustest/util/MathUtil.java index 4e85cd2a5..8903c8722 100644 --- a/tests/milvustest/src/main/java/com/zilliz/milvustest/util/MathUtil.java +++ b/tests/milvustest/src/main/java/com/zilliz/milvustest/util/MathUtil.java @@ -207,4 +207,41 @@ public static float generalRandomLessThanFloat(float floatNum){ return floatNum-random.nextInt(5)-1; } + public static short floatToFloat16(float value) { + int f = Float.floatToRawIntBits(value); + int s = (f >> 16) & 0x8000; + int e = ((f >> 23) & 0xff) - 127; + int m = f & 0x7fffff; + + if (e <= -15) { + // 如果指数小于等于-15,则将float16值设为0 + return 0; + } + if (e > 16) { + // 如果指数大于16,则将float16值设为最大值 + return (short) (s | 0x7bff); + } + if (e <= 0) { + m = (m | 0x800000) >> (1 - e); + return (short) (s | (m >> 13)); + } + if (e < 24) { + return (short) (s | ((e + 112) << 10) | (m >> 13)); + } + + return (short) (s | 0x7c00); + } + + public static short floatToBF16(float value) { + int floatValueBits = Float.floatToIntBits(value); + int sign = (floatValueBits >> 31) & 0x1; + int exponent = ((floatValueBits >> 23) & 0xFF) - 127 + 15; + int mantissa = (floatValueBits & 0x7FFFFF) >> 13; + + short bf16Value = (short) ((sign << 15) | (exponent << 10) | mantissa); + return bf16Value; + } + + + } diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/bulk/BulkWriteTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/bulk/BulkWriteTest.java index 831fad5a9..cbd47d02c 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/bulk/BulkWriteTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/bulk/BulkWriteTest.java @@ -45,13 +45,13 @@ public class BulkWriteTest extends BaseTest { String newCollection=""; CollectionSchemaParam collectionSchemaParam; - @BeforeClass + @BeforeClass(alwaysRun = true) public void initTestData(){ newCollection = CommonFunction.createNewCollectionWithJSONField(); collectionSchemaParam = CommonFunction.provideJsonCollectionSchema(); } - @AfterClass + @AfterClass(alwaysRun = true) public void clearTestData(){ milvusClient.dropCollection(DropCollectionParam.newBuilder() .withCollectionName(newCollection).build()); @@ -106,7 +106,7 @@ public void bulkWriteTest() throws IOException, InterruptedException, NoSuchAlgo Assert.assertEquals(collectionStatistics2.getData().getStats(0).getValue(), "10000"); } - @Test(description = "bulk remote write test",groups = {"Smoke"}) + @Test(description = "bulk remote write test") public void bulkRemoteWriteTest() throws IOException, InterruptedException, NoSuchAlgorithmException, InvalidKeyException { StorageConnectParam connectParam; if (Objects.equals(PropertyFilesUtil.getRunValue("storageType"), "azure")) { diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/bulkimport/BulkImportTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/bulkimport/BulkImportTest.java index 5e0397b8f..755231213 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/bulkimport/BulkImportTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/bulkimport/BulkImportTest.java @@ -296,7 +296,7 @@ private void createCollection(String collectionName, CollectionSchemaParam colle System.out.printf("Collection %s created%n", collectionName); } - @Test(description = "bulk remote import test",groups = {"Smoke"}) + @Test(description = "bulk remote import test") public void bulkRemoteImportTest() throws Exception { String cloudEndpoint = PropertyFilesUtil.getRunValue("cloudEndpoint"); String apiKey = PropertyFilesUtil.getRunValue("apikey"); diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/collection/CreateCollectionTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/collection/CreateCollectionTest.java index 3e57b63e2..4bd199110 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/collection/CreateCollectionTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/collection/CreateCollectionTest.java @@ -1,11 +1,13 @@ package com.zilliz.milvustest.collection; import com.zilliz.milvustest.common.BaseTest; +import com.zilliz.milvustest.common.CommonData; import com.zilliz.milvustest.util.MathUtil; import io.milvus.exception.ParamException; import io.milvus.grpc.DataType; import io.milvus.param.R; import io.milvus.param.RpcStatus; +import io.milvus.param.collection.CollectionSchemaParam; import io.milvus.param.collection.CreateCollectionParam; import io.milvus.param.collection.DropCollectionParam; import io.milvus.param.collection.FieldType; @@ -33,6 +35,13 @@ public class CreateCollectionTest extends BaseTest { public String arrayFieldCollection; + public String float16FieldCollection; + public String bf16FieldCollection; + + public String sparseVectorCollection; + + public String multiVectorCollection; + @DataProvider(name = "collectionByDataProvider") public Object[][] provideCollectionName() { return new String[][] {{"collection_" + MathUtil.getRandomString(10)}}; @@ -60,6 +69,22 @@ public void deleteTestData() { milvusClient.dropCollection( DropCollectionParam.newBuilder().withCollectionName(arrayFieldCollection).build()); } + if (float16FieldCollection != null) { + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(float16FieldCollection).build()); + } + if (bf16FieldCollection != null) { + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(bf16FieldCollection).build()); + } + if (sparseVectorCollection != null) { + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(sparseVectorCollection).build()); + } + if (multiVectorCollection != null) { + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(multiVectorCollection).build()); + } } @DataProvider(name = "dataTypeProvider") @@ -545,4 +570,139 @@ public void createCollectionWithArrayField(){ Assert.assertEquals(collection.getData().getMsg(), "Success"); } + @Test(description = "Create collection with float16 field",groups = {"Smoke"}) + public void createCollectionWithFloat16Vector(){ + float16FieldCollection = "Collection_" + MathUtil.getRandomString(10); + FieldType fieldType1 = + FieldType.newBuilder() + .withName("int64_field") + .withDataType(DataType.Int64) + .withPrimaryKey(true) + .withAutoID(false) + .build(); + FieldType fieldType2 = + FieldType.newBuilder() + .withName("float_vector") + .withDataType(DataType.Float16Vector) + .withDimension(128) + .build(); + CollectionSchemaParam schemaParam = CollectionSchemaParam.newBuilder().addFieldType(fieldType1).addFieldType(fieldType2).build(); + CreateCollectionParam createCollectionReq = + CreateCollectionParam.newBuilder() + .withCollectionName(float16FieldCollection) + .withDescription("Test" + float16FieldCollection + "search") + .withShardsNum(2) + .withSchema(schemaParam) + .build(); + R collection = milvusClient.createCollection(createCollectionReq); + Assert.assertEquals(collection.getStatus().toString(), "0"); + Assert.assertEquals(collection.getData().getMsg(), "Success"); + } + + @Test(description = "Create collection with bf16 field",groups = {"Smoke"}) + public void createCollectionWithBf16Vector(){ + bf16FieldCollection = "Collection_" + MathUtil.getRandomString(10); + FieldType fieldType1 = + FieldType.newBuilder() + .withName("int64_field") + .withDataType(DataType.Int64) + .withPrimaryKey(true) + .withAutoID(false) + .build(); + FieldType fieldType2 = + FieldType.newBuilder() + .withName("float_vector") + .withDataType(DataType.BFloat16Vector) + .withDimension(128) + .build(); + CollectionSchemaParam schemaParam = CollectionSchemaParam.newBuilder().addFieldType(fieldType1).addFieldType(fieldType2).build(); + CreateCollectionParam createCollectionReq = + CreateCollectionParam.newBuilder() + .withCollectionName(bf16FieldCollection) + .withDescription("Test" + bf16FieldCollection + "search") + .withShardsNum(2) + .withSchema(schemaParam) + .build(); + R collection = milvusClient.createCollection(createCollectionReq); + Assert.assertEquals(collection.getStatus().toString(), "0"); + Assert.assertEquals(collection.getData().getMsg(), "Success"); + } + + @Test(description = "Create collection with sparse vector field",groups = {"Smoke"}) + public void createCollectionWithSparseVector(){ + sparseVectorCollection = "Collection_" + MathUtil.getRandomString(10); + FieldType fieldType1 = + FieldType.newBuilder() + .withName("int64_field") + .withDataType(DataType.Int64) + .withPrimaryKey(true) + .withAutoID(false) + .build(); + FieldType fieldType2 = + FieldType.newBuilder() + .withName("float_vector") + .withDataType(DataType.SparseFloatVector) + .build(); + CollectionSchemaParam schemaParam = CollectionSchemaParam.newBuilder().addFieldType(fieldType1).addFieldType(fieldType2).build(); + CreateCollectionParam createCollectionReq = + CreateCollectionParam.newBuilder() + .withCollectionName(sparseVectorCollection) + .withDescription("Test" + sparseVectorCollection + "search") + .withShardsNum(2) + .withSchema(schemaParam) + .build(); + R collection = milvusClient.createCollection(createCollectionReq); + Assert.assertEquals(collection.getStatus().toString(), "0"); + Assert.assertEquals(collection.getData().getMsg(), "Success"); + } + + @Test(description = "Create collection with multi vector ",groups = {"Smoke"}) + public void createCollectionWithMultiVector(){ + multiVectorCollection = "Collection_" + MathUtil.getRandomString(10); + FieldType fieldType1 = + FieldType.newBuilder() + .withName("book_id") + .withDataType(DataType.Int64) + .withPrimaryKey(true) + .withAutoID(false) + .build(); + FieldType fieldType2 = + FieldType.newBuilder().withName("word_count").withDataType(DataType.Int64).build(); + FieldType fieldType3 = + FieldType.newBuilder() + .withName(CommonData.defaultVectorField) + .withDataType(DataType.FloatVector) + .withDimension(CommonData.dim) + .build(); + FieldType fieldType4 = + FieldType.newBuilder() + .withName(CommonData.defaultBinaryVectorField) + .withDataType(DataType.BinaryVector) + .withDimension(CommonData.dim) + .build(); + FieldType fieldType5 = + FieldType.newBuilder() + .withName(CommonData.defaultSparseVectorField) + .withDataType(DataType.SparseFloatVector) + .build(); + CollectionSchemaParam collectionSchemaParam = CollectionSchemaParam.newBuilder() + .addFieldType(fieldType1) + .addFieldType(fieldType2) + .addFieldType(fieldType3) + .addFieldType(fieldType4) + .addFieldType(fieldType5) + .build(); + CreateCollectionParam createCollectionReq = + CreateCollectionParam.newBuilder() + .withCollectionName(multiVectorCollection) + .withDescription("Test" + multiVectorCollection + "search") + .withShardsNum(1) + .withSchema(collectionSchemaParam) + .build(); + R collection = BaseTest.milvusClient.createCollection(createCollectionReq); + Assert.assertEquals(collection.getStatus().toString(), "0"); + Assert.assertEquals(collection.getData().getMsg(), "Success"); + } + + } diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/compaction/ManualCompactionTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/compaction/ManualCompactionTest.java index 800610c66..3a37c5a92 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/compaction/ManualCompactionTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/compaction/ManualCompactionTest.java @@ -56,7 +56,7 @@ public void dropCollection() { @Severity(SeverityLevel.BLOCKER) @Test( description = "performs a manual compaction.", - groups = {"Smoke"}) + groups = {"Smoke"},enabled = false) public void manualCompactionTest() { R responseR = milvusClient.manualCompact( diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/database/DatabaseTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/database/DatabaseTest.java index 4cf6e8775..f4a296a10 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/database/DatabaseTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/database/DatabaseTest.java @@ -190,7 +190,7 @@ public void createSameCollectionNameInDiffDatabase() { groups = {"Smoke"}) public void dropDefaultDatabase(){ R aDefault = milvusClient.dropDatabase(DropDatabaseParam.newBuilder().withDatabaseName("default").build()); - Assert.assertEquals(aDefault.getStatus().intValue(), 1); + Assert.assertEquals(aDefault.getStatus().intValue(), 65535); Assert.assertTrue(aDefault.getException().getMessage().contains("can not drop default")); } @@ -312,7 +312,7 @@ public void searchNonexistentCollectionWithDatabase(){ .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) .build(); R searchResultsR = milvusClient1.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 4); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 100); Assert.assertTrue(searchResultsR.getException().getMessage().contains("collection not found")); } @@ -353,7 +353,7 @@ public void queryNonexistentCollectionWithDatabase(){ .withExpr(SEARCH_PARAM) .build(); R queryResultsR = milvusClient1.query(queryParam); - Assert.assertEquals(queryResultsR.getStatus().intValue(), 4); + Assert.assertEquals(queryResultsR.getStatus().intValue(), 100); Assert.assertTrue(queryResultsR.getException().getMessage().contains("collection not found")); } diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/index/CreateIndexTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/index/CreateIndexTest.java index 4b65a4139..c2d810bbe 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/index/CreateIndexTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/index/CreateIndexTest.java @@ -15,6 +15,7 @@ import io.milvus.param.dml.QueryParam; import io.milvus.param.index.CreateIndexParam; import io.milvus.param.index.DropIndexParam; +import io.milvus.v2.common.IndexParam; import io.qameta.allure.*; import org.testng.Assert; import org.testng.annotations.AfterClass; @@ -92,6 +93,9 @@ public Object[][] providerIndexForBinaryCollection() { @Issue("https://github.com/milvus-io/milvus-sdk-java/issues/311") @Test(description = "Create index for collection sync", dataProvider = "FloatIndex",groups = {"Smoke"}) public void createIndexSync(IndexType indexType, MetricType metricType) { + if (indexType.toString().contains("GPU")&&metricType.equals(MetricType.COSINE)){ + return; + } R rpcStatusR = milvusClient.createIndex( CreateIndexParam.newBuilder() diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/index/IndexLoadTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/index/IndexLoadTest.java index cc2f1c813..65cca291d 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/index/IndexLoadTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/index/IndexLoadTest.java @@ -125,7 +125,7 @@ public void createIndexAfterLoadFloatCollection(IndexType indexType, MetricType .withCollectionName(collection) .build()); System.out.println("Drop index " + rpcStatusR4); - Assert.assertEquals(rpcStatusR4.getStatus().intValue(), 1); + Assert.assertEquals(rpcStatusR4.getStatus().intValue(), 65535); Assert.assertTrue(rpcStatusR4.getMessage().contains("index cannot be dropped, collection is loaded, please release it first")); // 6. release collection @@ -197,7 +197,7 @@ public void createIndexAfterLoadBinaryCollection(IndexType indexType, MetricType .withCollectionName(binaryCollection) .build()); System.out.println("Drop index " + rpcStatusR4); - Assert.assertEquals(rpcStatusR4.getStatus().intValue(), 1); + Assert.assertEquals(rpcStatusR4.getStatus().intValue(), 65535); Assert.assertTrue(rpcStatusR4.getMessage().contains("index cannot be dropped, collection is loaded, please release it first")); // 6. release collection diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/DeleteTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/DeleteTest.java index dca2e5a33..09b716c6f 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/DeleteTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/DeleteTest.java @@ -69,7 +69,7 @@ public void deleteDataInComplexExpWithUnload() { .withCollectionName(commonCollection) .withExpr("book_id <100") .build()); - Assert.assertEquals(mutationResultR.getStatus().intValue(), 1); + Assert.assertEquals(mutationResultR.getStatus().intValue(), 101); Assert.assertTrue(mutationResultR.getException().getMessage().contains("collection not loaded")); } diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/InsertTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/InsertTest.java index 567fb1716..f8369ab06 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/InsertTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/InsertTest.java @@ -37,11 +37,19 @@ public class InsertTest extends BaseTest { public String collectionWithJsonField; public String collectionWithDynamicField; + public String collectionWithFloat16Vector; + public String collectionWithBF16Vector; + private String collectionWithSparseVector; + private String collectionWithMultiVector; @BeforeClass(description = "provider collection",alwaysRun = true) public void providerData() { stringPKAndBinaryCollection = CommonFunction.createStringPKAndBinaryCollection(); collectionWithJsonField= CommonFunction.createNewCollectionWithJSONField(); collectionWithDynamicField= CommonFunction.createNewCollectionWithDynamicField(); + collectionWithFloat16Vector = CommonFunction.createFloat16Collection(); + collectionWithBF16Vector = CommonFunction.createBf16Collection(); + collectionWithSparseVector = CommonFunction.createSparseFloatVectorCollection(); + collectionWithMultiVector = CommonFunction.createMultiVectorCollection(); } @AfterClass(description = "delete test data",alwaysRun = true) @@ -52,6 +60,15 @@ public void deleteData() { DropCollectionParam.newBuilder().withCollectionName(collectionWithJsonField).build()); milvusClient.dropCollection( DropCollectionParam.newBuilder().withCollectionName(collectionWithDynamicField).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithFloat16Vector).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithBF16Vector).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithSparseVector).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithMultiVector).build()); + } @@ -467,4 +484,52 @@ public void insertFieldsAndRowsData(){ .withRows(jsonObjects) .build()); } + + @Severity(SeverityLevel.BLOCKER) + @Test(description = "Insert data into float16 vector collection ",groups = {"Smoke"}) + public void insertDataIntoFloat16VectorCollection(){ + List fields = CommonFunction.generateDataWithFloat16Vector(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withCollectionName(collectionWithFloat16Vector) + .withFields(fields) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + Assert.assertEquals(insert.getData().getSuccIndexCount(),1000); + } + + @Severity(SeverityLevel.BLOCKER) + @Test(description = "Insert data into bf16 vector collection ",groups = {"Smoke"}) + public void insertDataIntoBf16VectorCollection(){ + List fields = CommonFunction.generateDataWithBF16Vector(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withCollectionName(collectionWithBF16Vector) + .withFields(fields) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + Assert.assertEquals(insert.getData().getSuccIndexCount(),1000); + } + + @Test(description = "Insert data into sparse vector collection ",groups = {"Smoke"}) + public void insertDataIntoSparseVectorCollection(){ + List fields = CommonFunction.generateDataWithSparseFloatVector(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withCollectionName(collectionWithSparseVector) + .withFields(fields) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + Assert.assertEquals(insert.getData().getSuccIndexCount(),1000); + } + + @Test(description = "Insert data into multi vector collection ",groups = {"Smoke"}) + public void insertDataIntoMultiVectorCollection(){ + List fields = CommonFunction.generateDataWithMultiVector(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withFields(fields) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + Assert.assertEquals(insert.getData().getSuccIndexCount(),1000); + } + + } diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/UpsertTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/UpsertTest.java index 15b1c22aa..12de3233e 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/UpsertTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/insert/UpsertTest.java @@ -43,7 +43,7 @@ public void insertDataIntoCollection() { } @Severity(SeverityLevel.BLOCKER) - @Test(description = "UpsertTest data into collection",groups = {"master"}) + @Test(description = "UpsertTest data into collection",groups = {"Smoke"}) public void upsertDataIntoCollection() { Random ran = new Random(); List book_id_array = new ArrayList<>(); @@ -73,7 +73,7 @@ public void upsertDataIntoCollection() { @Severity(SeverityLevel.BLOCKER) - @Test(description = "Search after upsert collection",groups = {"master"},dependsOnMethods = {"upsertDataIntoCollection"}) + @Test(description = "Search after upsert collection",groups = {"Smoke"},dependsOnMethods = {"upsertDataIntoCollection"}) public void searchAfterUpsertCollection(){ //load milvusClient.loadCollection(LoadCollectionParam.newBuilder() @@ -89,7 +89,7 @@ public void searchAfterUpsertCollection(){ .withMetricType(MetricType.L2) .withOutFields(search_output_fields) .withTopK(SEARCH_K) - .withVectors(search_vectors) + .withFloatVectors(search_vectors) .withVectorFieldName(CommonData.defaultVectorField) .withParams(SEARCH_PARAM) .withConsistencyLevel(ConsistencyLevelEnum.STRONG) @@ -100,11 +100,6 @@ public void searchAfterUpsertCollection(){ SearchResultsWrapper searchResultsWrapper = new SearchResultsWrapper(searchResultsR.getData().getResults()); Assert.assertEquals(searchResultsWrapper.getFieldData("word_count", 0).size(), 10); - List word_count = searchResultsWrapper.getFieldWrapper("word_count").getFieldData(); - for (Object o : word_count) { - System.out.println(Integer.parseInt(o.toString())); - Assert.assertTrue(Integer.parseInt(o.toString())>=20000); - } } diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/mmap/AlterCollectionTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/mmap/AlterCollectionTest.java new file mode 100644 index 000000000..33496b0e1 --- /dev/null +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/mmap/AlterCollectionTest.java @@ -0,0 +1,250 @@ +package com.zilliz.milvustest.mmap; + +import com.google.common.collect.Lists; +import com.zilliz.milvustest.common.BaseTest; +import com.zilliz.milvustest.common.CommonData; +import com.zilliz.milvustest.common.CommonFunction; +import io.milvus.common.clientenum.ConsistencyLevelEnum; +import io.milvus.grpc.MutationResult; +import io.milvus.grpc.SearchResults; +import io.milvus.param.*; +import io.milvus.param.collection.AlterCollectionParam; +import io.milvus.param.collection.DropCollectionParam; +import io.milvus.param.collection.LoadCollectionParam; +import io.milvus.param.dml.AnnSearchParam; +import io.milvus.param.dml.HybridSearchParam; +import io.milvus.param.dml.InsertParam; +import io.milvus.param.dml.SearchParam; +import io.milvus.param.dml.ranker.RRFRanker; +import io.milvus.response.SearchResultsWrapper; +import io.qameta.allure.Epic; +import io.qameta.allure.Feature; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.SortedMap; + +/** + * @Author yongpeng.li + * @Date 2024/4/12 15:21 + */ +@Epic("MMAP") +@Feature("AlterCollection") +public class AlterCollectionTest extends BaseTest { + private String collectionMMapScalar; + + private String collectionWithBinaryVector; + private String collectionWithSparseVector; + private String collectionWithMultiVector; + + @BeforeClass(alwaysRun = true) + public void provideTestData(){ + collectionMMapScalar= CommonFunction.createNewCollection(); + CommonFunction.insertDataIntoCollection(collectionMMapScalar,null,10000); + CommonFunction.createIndexWithoutLoad(collectionMMapScalar,IndexType.HNSW,MetricType.L2, CommonData.defaultVectorField); + + collectionWithBinaryVector=CommonFunction.createBinaryCollection(); + CommonFunction.insertDataIntoCollection(collectionWithBinaryVector, CommonFunction.generateBinaryData(10000)); + CommonFunction.createIndexWithoutLoad(collectionWithBinaryVector,IndexType.BIN_IVF_FLAT,MetricType.HAMMING,CommonData.defaultBinaryVectorField); + + collectionWithSparseVector = CommonFunction.createSparseFloatVectorCollection(); + CommonFunction.insertDataIntoCollection(collectionWithSparseVector,CommonFunction.generateDataWithSparseFloatVector(10000)); + CommonFunction.createIndexWithoutLoad(collectionWithSparseVector,IndexType.SPARSE_INVERTED_INDEX,MetricType.IP,CommonData.defaultSparseVectorField); + + collectionWithMultiVector = CommonFunction.createMultiVectorCollection(); + List fields = CommonFunction.generateDataWithMultiVector(10000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withFields(fields) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.HNSW, MetricType.L2, CommonData.defaultVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.BIN_FLAT, MetricType.HAMMING, CommonData.defaultBinaryVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.SPARSE_INVERTED_INDEX, MetricType.IP, CommonData.defaultSparseVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector,IndexType.HNSW,MetricType.L2,CommonData.defaultFloat16VectorField); + + } + @AfterClass(alwaysRun = true) + public void cleanTestData(){ + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionMMapScalar).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithSparseVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithMultiVector).build()); + } + + + @Test(description = "Enable mmap on scalar field",groups = {"Smoke"}) + public void enableMMAPCollection() { + R rpcStatusR = milvusClient.alterCollection(AlterCollectionParam.newBuilder() + .withCollectionName(collectionMMapScalar) + .withMMapEnabled(true) + .withProperty(Constant.MMAP_ENABLED, Boolean.toString(false)).build()); + Assert.assertEquals(rpcStatusR.getStatus(),0); + } + + @Test(description = "Enable mmap collection with binary vector",groups = {"Smoke"}) + public void enableMMAPCollectionWithBinaryVector() { + R rpcStatusR = milvusClient.alterCollection(AlterCollectionParam.newBuilder() + .withCollectionName(collectionWithBinaryVector).withMMapEnabled(true).build()); + Assert.assertEquals(rpcStatusR.getStatus(),0); + } + @Test(description = "Enable mmap collection with sparse vector",groups = {"Smoke"}) + public void enableMMAPCollectionWithSparseVector() { + R rpcStatusR = milvusClient.alterCollection(AlterCollectionParam.newBuilder() + .withCollectionName(collectionWithSparseVector).withMMapEnabled(true).build()); + Assert.assertEquals(rpcStatusR.getStatus(),0); + } + + @Test(description = "Enable mmap collection with multi vector",groups = {"Smoke"}) + public void enableMMAPCollectionWithMultiVector() { + R rpcStatusR = milvusClient.alterCollection(AlterCollectionParam.newBuilder() + .withCollectionName(collectionWithMultiVector).withMMapEnabled(true).build()); + Assert.assertEquals(rpcStatusR.getStatus(),0); + } + + @Test(description = "Enable mmap fail when the collection is loaded",groups = {"Smoke"},dependsOnMethods = {"enableMMAPCollection"}) + public void createIndexAfterLoadFloatCollection() { + milvusClient.loadCollection(LoadCollectionParam.newBuilder() + .withCollectionName(collectionMMapScalar).build()); + R rpcStatusR = milvusClient.alterCollection(AlterCollectionParam.newBuilder() + .withCollectionName(collectionMMapScalar).withMMapEnabled(true).build()); + Assert.assertEquals(rpcStatusR.getStatus(),104); + } + + @Test(description = "search collection after enable mmap",groups = {"Smoke"},dependsOnMethods = {"createIndexAfterLoadFloatCollection"}) + public void searchCollectionAfterEnableMMap(){ + Integer SEARCH_K = 2; // TopK + List search_output_fields = Arrays.asList("*"); + List> search_vectors = CommonFunction.generateFloatVectors(1,CommonData.dim); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionMMapScalar) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData(CommonData.defaultVectorField, 0).size(), 2); + } + + @Test(description = "search binary vector collection after enable mmap",groups = {"Smoke"},dependsOnMethods = {"enableMMAPCollectionWithBinaryVector"}) + public void searchBinaryCollectionAfterEnableMMap(){ + R rpcStatusR = milvusClient.loadCollection(LoadCollectionParam.newBuilder().withCollectionName(collectionWithBinaryVector).build()); + System.out.println(rpcStatusR); + Integer SEARCH_K = 2; // TopK + List search_output_fields = Collections.singletonList("*"); + List byteBuffers = CommonFunction.generateBinaryVectors(1, CommonData.dim); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithBinaryVector) + .withMetricType(MetricType.HAMMING) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(Lists.newArrayList(byteBuffers)) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.BIN_IVF_FLAT)) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData(CommonData.defaultBinaryVectorField, 0).size(), 2); + } + + @Test(description = "search sparse vector collection after enable mmap",groups = {"Smoke"},dependsOnMethods = {"enableMMAPCollectionWithSparseVector"}) + public void searchSparseCollectionAfterEnableMMap(){ + R rpcStatusR = milvusClient.loadCollection(LoadCollectionParam.newBuilder().withCollectionName(collectionWithSparseVector).build()); + System.out.println(rpcStatusR); + Integer SEARCH_K = 2; // TopK + List search_output_fields = Collections.singletonList("*"); + SortedMap longFloatSortedMap = CommonFunction.generateSparseVector(); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithSparseVector) + .withMetricType(MetricType.IP) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withSparseFloatVectors(Lists.newArrayList(longFloatSortedMap)) + .withVectorFieldName(CommonData.defaultSparseVectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.SPARSE_INVERTED_INDEX)) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData(CommonData.defaultSparseVectorField, 0).size(), 2); + } + + @Test(description = "Hybrid search collection after enable mmap",groups = {"Smoke"},dependsOnMethods = {"enableMMAPCollectionWithMultiVector"}) + public void hybridSearchCollectionAfterEnableMMap(){ + R rpcStatusR = milvusClient.loadCollection(LoadCollectionParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withSyncLoad(true).build()); + // search + AnnSearchParam floatVSP= AnnSearchParam.newBuilder() + .withFloatVectors(CommonFunction.generateFloatVectors(1,CommonData.dim)) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withVectorFieldName(CommonData.defaultVectorField) + .withMetricType(MetricType.L2) + .withTopK(10).build(); + AnnSearchParam binaryVSP= AnnSearchParam.newBuilder() + .withBinaryVectors(CommonFunction.generateBinaryVectors(1,CommonData.dim)) + .withParams(CommonFunction.provideExtraParam(IndexType.BIN_FLAT)) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withMetricType(MetricType.HAMMING) + .withTopK(20).build(); + AnnSearchParam sparseVSP= AnnSearchParam.newBuilder() + .withSparseFloatVectors(Lists.newArrayList(CommonFunction.generateSparseVector())) + .withParams(CommonFunction.provideExtraParam(IndexType.SPARSE_INVERTED_INDEX)) + .withVectorFieldName(CommonData.defaultSparseVectorField) + .withMetricType(MetricType.IP) + .withTopK(30).build(); + AnnSearchParam float16VSP= AnnSearchParam.newBuilder() + .withFloat16Vectors(CommonFunction.generateFloat16Vectors(CommonData.dim,1)) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withVectorFieldName(CommonData.defaultFloat16VectorField) + .withMetricType(MetricType.L2) + .withTopK(30).build(); + + HybridSearchParam hybridSearchParam= HybridSearchParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withOutFields(Lists.newArrayList(CommonData.defaultVectorField,CommonData.defaultBinaryVectorField,CommonData.defaultSparseVectorField)) + .withTopK(40) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .addSearchRequest(binaryVSP) + .addSearchRequest(sparseVSP) + .addSearchRequest(floatVSP) + .addSearchRequest(float16VSP) + .withRanker(RRFRanker.newBuilder() + .withK(2) + .build()) + .build(); + R searchResultsR = milvusClient.hybridSearch(hybridSearchParam); + + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData(CommonData.defaultVectorField, 0).size(), 40); + + } + + + +} diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/mmap/AlterIndexTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/mmap/AlterIndexTest.java new file mode 100644 index 000000000..78ba8cb82 --- /dev/null +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/mmap/AlterIndexTest.java @@ -0,0 +1,250 @@ +package com.zilliz.milvustest.mmap; + +import com.google.common.collect.Lists; +import com.zilliz.milvustest.common.BaseTest; +import com.zilliz.milvustest.common.CommonData; +import com.zilliz.milvustest.common.CommonFunction; +import io.milvus.common.clientenum.ConsistencyLevelEnum; +import io.milvus.grpc.MutationResult; +import io.milvus.grpc.SearchResults; +import io.milvus.param.IndexType; +import io.milvus.param.MetricType; +import io.milvus.param.R; +import io.milvus.param.RpcStatus; +import io.milvus.param.collection.AlterCollectionParam; +import io.milvus.param.collection.DropCollectionParam; +import io.milvus.param.collection.LoadCollectionParam; +import io.milvus.param.dml.AnnSearchParam; +import io.milvus.param.dml.HybridSearchParam; +import io.milvus.param.dml.InsertParam; +import io.milvus.param.dml.SearchParam; +import io.milvus.param.dml.ranker.RRFRanker; +import io.milvus.param.index.AlterIndexParam; +import io.milvus.response.SearchResultsWrapper; +import io.qameta.allure.Epic; +import io.qameta.allure.Feature; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.Test; + +import java.nio.ByteBuffer; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; + +/** + * @Author yongpeng.li + * @Date 2024/4/15 11:20 + */ +@Epic("MMAP") +@Feature("AlterIndex") +public class AlterIndexTest extends BaseTest { + private String collectionWithFloatVector; + private String collectionWithBinaryVector; + private String collectionWithSparseVector; + private String collectionWithMultiVector; + + @BeforeClass(alwaysRun = true) + public void provideTestData() { + collectionWithFloatVector = CommonFunction.createNewCollection(); + CommonFunction.insertDataIntoCollection(collectionWithFloatVector, null, 10000); + CommonFunction.createIndexWithoutLoad(collectionWithFloatVector, IndexType.HNSW, MetricType.L2, CommonData.defaultVectorField); + + collectionWithBinaryVector = CommonFunction.createBinaryCollection(); + CommonFunction.insertDataIntoCollection(collectionWithBinaryVector, CommonFunction.generateBinaryData(10000)); + CommonFunction.createIndexWithoutLoad(collectionWithBinaryVector, IndexType.BIN_IVF_FLAT, MetricType.HAMMING, CommonData.defaultBinaryVectorField); + + collectionWithSparseVector = CommonFunction.createSparseFloatVectorCollection(); + CommonFunction.insertDataIntoCollection(collectionWithSparseVector, CommonFunction.generateDataWithSparseFloatVector(10000)); + CommonFunction.createIndexWithoutLoad(collectionWithSparseVector, IndexType.SPARSE_INVERTED_INDEX, MetricType.IP, CommonData.defaultSparseVectorField); + + collectionWithMultiVector = CommonFunction.createMultiVectorCollection(); + List fields = CommonFunction.generateDataWithMultiVector(10000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withFields(fields) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.HNSW, MetricType.L2, CommonData.defaultVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.BIN_FLAT, MetricType.HAMMING, CommonData.defaultBinaryVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.SPARSE_INVERTED_INDEX, MetricType.IP, CommonData.defaultSparseVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector,IndexType.HNSW,MetricType.L2,CommonData.defaultFloat16VectorField); + + } + + @AfterClass(alwaysRun = true) + public void cleanTestData() { + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithFloatVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithSparseVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithBinaryVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithMultiVector).build()); + } + + @Test(description = "Enable mmap index for float vector collection", groups = {"Smoke"}) + public void enableMMAPIndexForFloatVectorCollection() { + R rpcStatusR = milvusClient.alterIndex(AlterIndexParam.newBuilder() + .withCollectionName(collectionWithFloatVector) + .withIndexName("idx_" + CommonData.defaultVectorField) + .withMMapEnabled(true) + .build()); + Assert.assertEquals(rpcStatusR.getStatus(), 0); + } + + @Test(description = "Enable mmap index for binary vector collection",groups = {"Smoke"}) + public void enableMMAPIndexForBinaryVectorCollection() { + R rpcStatusR = milvusClient.alterIndex(AlterIndexParam.newBuilder() + .withCollectionName(collectionWithBinaryVector) + .withIndexName("idx_"+CommonData.defaultBinaryVectorField) + .withMMapEnabled(true) + .build()); + Assert.assertEquals(rpcStatusR.getStatus(),0); + } + + @Test(description = "Enable mmap index for sparse vector collection",enabled = false) + public void enableMMAPIndexForSparseVectorCollection() { + R rpcStatusR = milvusClient.alterIndex(AlterIndexParam.newBuilder() + .withCollectionName(collectionWithSparseVector) + .withIndexName("idx_"+CommonData.defaultSparseVectorField) + .withMMapEnabled(true) + .build()); + Assert.assertEquals(rpcStatusR.getStatus(),0); + } + + @Test(description = "Enable mmap index for multi vector collection",groups = {"Smoke"}) + public void enableMMAPIndexForMultiVectorCollection() { + R rpcStatusR1 = milvusClient.alterIndex(AlterIndexParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withIndexName("idx_"+CommonData.defaultVectorField) + .withMMapEnabled(true) + .build()); + R rpcStatusR2 = milvusClient.alterIndex(AlterIndexParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withIndexName("idx_"+CommonData.defaultBinaryVectorField) + .withMMapEnabled(true) + .build()); +// R rpcStatusR3 = milvusClient.alterIndex(AlterIndexParam.newBuilder() +// .withCollectionName(collectionWithMultiVector) +// .withIndexName("idx_"+CommonData.defaultSparseVectorField) +// .withMMapEnabled(false) +// .build()); + Assert.assertEquals(rpcStatusR1.getStatus(),0); + Assert.assertEquals(rpcStatusR2.getStatus(),0); +// Assert.assertEquals(rpcStatusR3.getStatus(),0); + } + + @Test(description = "Enable index mmap failed when the collection is loaded",groups = {"Smoke"},dependsOnMethods = {"enableMMAPIndexForFloatVectorCollection"}) + public void createIndexAfterLoadFloatCollection() { + milvusClient.loadCollection(LoadCollectionParam.newBuilder() + .withCollectionName(collectionWithFloatVector).build()); + R rpcStatusR = milvusClient.alterIndex(AlterIndexParam.newBuilder() + .withCollectionName(collectionWithFloatVector) + .withIndexName("idx_" + CommonData.defaultVectorField) + .withMMapEnabled(true) + .build()); + Assert.assertEquals(rpcStatusR.getStatus(),104); + } + + @Test(description = "Search float vector collection after enable mmap index",groups = {"Smoke"},dependsOnMethods = {"createIndexAfterLoadFloatCollection"}) + public void searchFloatVectorCollectionAfterEnableMMapIndex(){ + Integer SEARCH_K = 2; // TopK + List search_output_fields = Arrays.asList("*"); + List> search_vectors = CommonFunction.generateFloatVectors(1,CommonData.dim); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithFloatVector) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData(CommonData.defaultVectorField, 0).size(), 2); + } + + @Test(description = "search binary vector collection after enable mmap index",groups = {"Smoke"},dependsOnMethods = {"enableMMAPIndexForBinaryVectorCollection"}) + public void searchBinaryVectorCollectionAfterEnableMMapIndex(){ + R rpcStatusR = milvusClient.loadCollection(LoadCollectionParam.newBuilder().withCollectionName(collectionWithBinaryVector).build()); + System.out.println(rpcStatusR); + Integer SEARCH_K = 2; // TopK + List search_output_fields = Collections.singletonList("*"); + List byteBuffers = CommonFunction.generateBinaryVectors(1, CommonData.dim); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithBinaryVector) + .withMetricType(MetricType.HAMMING) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(Lists.newArrayList(byteBuffers)) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.BIN_IVF_FLAT)) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData(CommonData.defaultBinaryVectorField, 0).size(), 2); + } + + @Test(description = "Hybrid search collection after enable mmap index",groups = {"Smoke"},dependsOnMethods = {"enableMMAPIndexForMultiVectorCollection"}) + public void hybridSearchCollectionAfterEnableMMap(){ + R rpcStatusR = milvusClient.loadCollection(LoadCollectionParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withSyncLoad(true).build()); + // search + AnnSearchParam floatVSP= AnnSearchParam.newBuilder() + .withFloatVectors(CommonFunction.generateFloatVectors(1,CommonData.dim)) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withVectorFieldName(CommonData.defaultVectorField) + .withMetricType(MetricType.L2) + .withTopK(10).build(); + AnnSearchParam binaryVSP= AnnSearchParam.newBuilder() + .withBinaryVectors(CommonFunction.generateBinaryVectors(1,CommonData.dim)) + .withParams(CommonFunction.provideExtraParam(IndexType.BIN_FLAT)) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withMetricType(MetricType.HAMMING) + .withTopK(20).build(); + AnnSearchParam sparseVSP= AnnSearchParam.newBuilder() + .withSparseFloatVectors(Lists.newArrayList(CommonFunction.generateSparseVector())) + .withParams(CommonFunction.provideExtraParam(IndexType.SPARSE_INVERTED_INDEX)) + .withVectorFieldName(CommonData.defaultSparseVectorField) + .withMetricType(MetricType.IP) + .withTopK(30).build(); + AnnSearchParam float16VSP= AnnSearchParam.newBuilder() + .withFloat16Vectors(CommonFunction.generateFloat16Vectors(CommonData.dim,1)) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withVectorFieldName(CommonData.defaultFloat16VectorField) + .withMetricType(MetricType.L2) + .withTopK(30).build(); + HybridSearchParam hybridSearchParam= HybridSearchParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withOutFields(Lists.newArrayList(CommonData.defaultVectorField,CommonData.defaultBinaryVectorField,CommonData.defaultSparseVectorField)) + .withTopK(40) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .addSearchRequest(binaryVSP) + .addSearchRequest(sparseVSP) + .addSearchRequest(floatVSP) + .addSearchRequest(float16VSP) + .withRanker(RRFRanker.newBuilder() + .withK(2) + .build()) + .build(); + R searchResultsR = milvusClient.hybridSearch(hybridSearchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData(CommonData.defaultVectorField, 0).size(), 40); + + } +} diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/query/MultipleArraysDataFactory.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/query/MultipleArraysDataFactory.java new file mode 100644 index 000000000..e56bc4fa3 --- /dev/null +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/query/MultipleArraysDataFactory.java @@ -0,0 +1,64 @@ +package com.zilliz.milvustest.query; + +import org.testng.annotations.DataProvider; +import org.testng.annotations.Factory; +import org.testng.annotations.Test; + +public class MultipleArraysDataFactory { + + @DataProvider(name = "dataSets") + public static Object[][] dataSets() { + String[] array1 = {"A", "B", "C"}; + String[] array2 = {"1", "2", "3"}; + String[] array3 = {"X", "Y", "Z"}; + String[] array4 = {"10", "20", "30"}; + String[] array5 = {"I", "II", "III"}; + + Object[][] testData = new Object[array1.length * array2.length * array3.length * array4.length * array5.length][5]; + int index = 0; + for (String value1 : array1) { + for (String value2 : array2) { + for (String value3 : array3) { + for (String value4 : array4) { + for (String value5 : array5) { + testData[index][0] = value1; + testData[index][1] = value2; + testData[index][2] = value3; + testData[index][3] = value4; + testData[index][4] = value5; + index++; + } + } + } + } + } + return testData; + } + + @Factory(dataProvider = "dataSets") + public Object[] createInstances(String param1, String param2, String param3, String param4, String param5) { + return new Object[] { new TestData(param1, param2, param3, param4, param5) }; + } + + public class TestData { + private String param1; + private String param2; + private String param3; + private String param4; + private String param5; + + public TestData(String param1, String param2, String param3, String param4, String param5) { + this.param1 = param1; + this.param2 = param2; + this.param3 = param3; + this.param4 = param4; + this.param5 = param5; + } + + @Test + public void testMultipleArraysData() { + System.out.println("Parameters: " + param1 + ", " + param2 + ", " + param3 + ", " + param4 + ", " + param5); + // 在这里执行测试逻辑 + } + } +} diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/query/QueryIteratorTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/query/QueryIteratorTest.java new file mode 100644 index 000000000..54ff03065 --- /dev/null +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/query/QueryIteratorTest.java @@ -0,0 +1,119 @@ +package com.zilliz.milvustest.query; + +import com.google.common.collect.Lists; +import com.zilliz.milvustest.common.BaseTest; +import com.zilliz.milvustest.common.CommonData; +import com.zilliz.milvustest.common.CommonFunction; +import io.milvus.common.clientenum.ConsistencyLevelEnum; +import io.milvus.grpc.MutationResult; +import io.milvus.orm.iterator.QueryIterator; +import io.milvus.orm.iterator.SearchIterator; +import io.milvus.param.IndexType; +import io.milvus.param.MetricType; +import io.milvus.param.R; +import io.milvus.param.collection.DropCollectionParam; +import io.milvus.param.dml.InsertParam; +import io.milvus.param.dml.QueryIteratorParam; +import io.milvus.param.dml.SearchIteratorParam; +import io.milvus.response.QueryResultsWrapper; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.util.List; + +/** + * @Author yongpeng.li + * @Date 2024/4/18 10:01 + */ +public class QueryIteratorTest extends BaseTest { + private String collectionWithFloatVector; + private String collectionWithBinaryVector; + private String collectionWithSparseVector; + + private String collectionWithFloat16Vector; + private String collectionWithBF16Vector; + + + @BeforeClass(alwaysRun = true) + public void provideTestData() { + collectionWithFloatVector = CommonFunction.createNewCollection(); + CommonFunction.insertDataIntoCollection(collectionWithFloatVector, null, 10000); + CommonFunction.createIndexWithLoad(collectionWithFloatVector, IndexType.HNSW, MetricType.L2, CommonData.defaultVectorField); + + collectionWithBinaryVector = CommonFunction.createBinaryCollection(); + CommonFunction.insertDataIntoCollection(collectionWithBinaryVector, CommonFunction.generateBinaryData(10000)); + CommonFunction.createIndexWithLoad(collectionWithBinaryVector, IndexType.BIN_FLAT, MetricType.HAMMING, CommonData.defaultBinaryVectorField); + + collectionWithSparseVector = CommonFunction.createSparseFloatVectorCollection(); + CommonFunction.insertDataIntoCollection(collectionWithSparseVector, CommonFunction.generateDataWithSparseFloatVector(100000)); + CommonFunction.createIndexWithLoad(collectionWithSparseVector, IndexType.SPARSE_INVERTED_INDEX, MetricType.IP, CommonData.defaultSparseVectorField); + + + + collectionWithFloat16Vector = CommonFunction.createFloat16Collection(); + CommonFunction.insertDataIntoCollection(collectionWithFloat16Vector,CommonFunction.generateDataWithFloat16Vector(10000)); + CommonFunction.createIndexWithLoad(collectionWithFloat16Vector,IndexType.HNSW,MetricType.L2,CommonData.defaultFloat16VectorField); + + collectionWithBF16Vector = CommonFunction.createBf16Collection(); + CommonFunction.insertDataIntoCollection(collectionWithBF16Vector,CommonFunction.generateDataWithBF16Vector(10000)); + CommonFunction.createIndexWithLoad(collectionWithBF16Vector,IndexType.HNSW,MetricType.L2,CommonData.defaultBF16VectorField); + + } + + @AfterClass(alwaysRun = true) + public void cleanTestData() { + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithFloatVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithSparseVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithBinaryVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithFloat16Vector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithBF16Vector).build()); + } + + @DataProvider(name = "testData") // limit ,batchSize, expect1, expect2 + public Object[][] provideTestDataParam(){ + return new Object[][]{ + {50L,10L,10,10,collectionWithFloatVector}, + {10L,10L,10,0,collectionWithFloatVector}, + {50L,100L,50,0,collectionWithFloatVector}, + {50L,10L,10,10,collectionWithBinaryVector}, + {10L,10L,10,0,collectionWithBinaryVector}, + {50L,100L,50,0,collectionWithBinaryVector}, + {50L,10L,10,10,collectionWithSparseVector}, + {10L,10L,10,0,collectionWithSparseVector}, + {50L,100L,50,0,collectionWithSparseVector}, + {50L,10L,10,10,collectionWithFloat16Vector}, + {10L,10L,10,0,collectionWithFloat16Vector}, + {50L,100L,50,0,collectionWithFloat16Vector}, + {50L,10L,10,10,collectionWithBF16Vector}, + {10L,10L,10,0,collectionWithBF16Vector}, + {50L,100L,50,0,collectionWithBF16Vector}, + }; + } + + @Test(description = "Query Iterator by float vector collection",groups = {"Smoke"},dataProvider = "testData") + public void queryIterator(long limit,long batchSize,int expect1,int expect2,String collection) { + R queryIteratorR = + milvusClient.queryIterator(QueryIteratorParam.newBuilder() + .withCollectionName(collection) + .withOutFields(Lists.newArrayList("*")) + .withBatchSize(batchSize) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .withLimit(limit) + .build()); + + Assert.assertEquals(queryIteratorR.getStatus(),0); + Assert.assertEquals(queryIteratorR.getData().next().size(),expect1); + Assert.assertEquals(queryIteratorR.getData().next().size(),expect2); + } + + + +} diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/query/QueryTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/query/QueryTest.java index 6401fcb64..e3c5b62be 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/query/QueryTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/query/QueryTest.java @@ -7,7 +7,6 @@ import com.zilliz.milvustest.util.MathUtil; import io.milvus.common.clientenum.ConsistencyLevelEnum; import io.milvus.exception.ParamException; -import io.milvus.grpc.DataType; import io.milvus.grpc.MutationResult; import io.milvus.grpc.QueryResults; import io.milvus.param.IndexType; @@ -49,6 +48,13 @@ public class QueryTest extends BaseTest { public String collectionWithArrayField; + private String collectionWithSparseVector; + + private String collectionWithMultiVector; + private String collectionWithFloat16Vector; + private String collectionWithBf16Vector; + + @BeforeClass(description = "load collection first",alwaysRun = true) public void loadCollection() { milvusClient.loadCollection( @@ -68,6 +74,10 @@ public void loadCollection() { collectionWithJsonField= CommonFunction.createNewCollectionWithJSONField(); collectionWithDynamicField= CommonFunction.createNewCollectionWithDynamicField(); collectionWithArrayField= CommonFunction.createNewCollectionWithArrayField(); + collectionWithSparseVector = CommonFunction.createSparseFloatVectorCollection(); + collectionWithFloat16Vector=CommonFunction.createFloat16Collection(); + collectionWithBf16Vector=CommonFunction.createBf16Collection(); + collectionWithMultiVector = CommonFunction.createMultiVectorCollection(); } @DataProvider(name = "providerPartition") @@ -99,6 +109,14 @@ public void releaseCollection() { DropCollectionParam.newBuilder().withCollectionName(collectionWithDynamicField).build()); milvusClient.dropCollection( DropCollectionParam.newBuilder().withCollectionName(collectionWithArrayField).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithSparseVector).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithMultiVector).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithFloat16Vector).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithBf16Vector).build()); } @DataProvider(name = "providerConsistency") @@ -217,6 +235,14 @@ public Object[][] provideStringExpression() { }; } + @DataProvider(name="sparseIndex") + public Object[][] provideSparseIndex(){ + return new IndexType[][]{ + {IndexType.SPARSE_INVERTED_INDEX} + ,{IndexType.SPARSE_WAND} + }; + } + @Test(description = "int PK and float vector query", dataProvider = "providerPartition",groups = {"Smoke"}) @Severity(SeverityLevel.BLOCKER) public void intPKAndFloatVectorQuery(Boolean usePart) { @@ -1146,6 +1172,110 @@ public void queryCollectionWithArrayField() { } + @Test(description = "query collection with sparse vector",groups = {"Smoke"},dataProvider = "sparseIndex") + public void queryCollectionWithSparseVector(IndexType indexType) { + List fields = CommonFunction.generateDataWithSparseFloatVector(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withCollectionName(collectionWithSparseVector) + .withFields(fields) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + CommonFunction.createIndexWithLoad(collectionWithSparseVector, indexType, MetricType.IP, CommonData.defaultSparseVectorField); + //query + List outFields = Collections.singletonList("*"); + QueryParam queryParam = + QueryParam.newBuilder() + .withCollectionName(collectionWithSparseVector) + .withOutFields(outFields) +// .withExpr(expr) + .withLimit(100L).withOffset(100L) + .build(); + R queryResultsR = milvusClient.query(queryParam); + QueryResultsWrapper wrapperQuery = new QueryResultsWrapper(queryResultsR.getData()); + Assert.assertEquals(queryResultsR.getStatus().intValue(), 0); + Assert.assertTrue(wrapperQuery.getFieldWrapper(CommonData.defaultSparseVectorField).getFieldData().size() >= 4); + } + + @Test(description = "query collection with float16 vector",groups = {"Smoke"},dataProvider = "FloatIndex") + public void queryCollectionWithFloat16Vector(IndexType indexType,MetricType metricType) { + List fields = CommonFunction.generateDataWithFloat16Vector(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withCollectionName(collectionWithFloat16Vector) + .withFields(fields) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + CommonFunction.createIndexWithLoad(collectionWithFloat16Vector, indexType, metricType, CommonData.defaultFloat16VectorField); + //query + List outFields = Collections.singletonList("*"); + QueryParam queryParam = + QueryParam.newBuilder() + .withCollectionName(collectionWithFloat16Vector) + .withOutFields(outFields) + .withLimit(100L).withOffset(10L) + .build(); + R queryResultsR = milvusClient.query(queryParam); + QueryResultsWrapper wrapperQuery = new QueryResultsWrapper(queryResultsR.getData()); + Assert.assertEquals(queryResultsR.getStatus().intValue(), 0); + Assert.assertTrue(wrapperQuery.getFieldWrapper(CommonData.defaultFloat16VectorField).getFieldData().size() >= 4); + } + + @Test(description = "query collection with bf16 vector",groups = {"Smoke"},dataProvider = "FloatIndex") + public void queryCollectionWithBF16Vector(IndexType indexType,MetricType metricType) { + List fields = CommonFunction.generateDataWithBF16Vector(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withCollectionName(collectionWithBf16Vector) + .withFields(fields) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + CommonFunction.createIndexWithLoad(collectionWithBf16Vector, indexType, metricType, CommonData.defaultBF16VectorField); + //query + List outFields = Collections.singletonList("*"); + QueryParam queryParam = + QueryParam.newBuilder() + .withCollectionName(collectionWithBf16Vector) + .withOutFields(outFields) + .withLimit(100L).withOffset(10L) + .build(); + R queryResultsR = milvusClient.query(queryParam); + QueryResultsWrapper wrapperQuery = new QueryResultsWrapper(queryResultsR.getData()); + Assert.assertEquals(queryResultsR.getStatus().intValue(), 0); + Assert.assertTrue(wrapperQuery.getFieldWrapper(CommonData.defaultBF16VectorField).getFieldData().size() >= 4); + } + + + @Test(description = "query collection with multi vector",groups = {"Smoke"}) + @Severity(SeverityLevel.BLOCKER) + public void queryCollectionWithMultiVector() { + List fields = CommonFunction.generateDataWithMultiVector(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withFields(fields) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.HNSW, MetricType.L2, CommonData.defaultVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.BIN_FLAT, MetricType.HAMMING, CommonData.defaultBinaryVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.SPARSE_INVERTED_INDEX, MetricType.IP, CommonData.defaultSparseVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.HNSW, MetricType.L2, CommonData.defaultFloat16VectorField); + R rpcStatusR = milvusClient.loadCollection(LoadCollectionParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withSyncLoad(true).build()); + System.out.println(rpcStatusR); + //query + List outFields = Collections.singletonList("*"); + QueryParam queryParam = + QueryParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withOutFields(outFields) +// .withExpr(expr) + .withLimit(100L).withOffset(100L) + .build(); + R queryResultsR = milvusClient.query(queryParam); + QueryResultsWrapper wrapperQuery = new QueryResultsWrapper(queryResultsR.getData()); + Assert.assertEquals(queryResultsR.getStatus().intValue(), 0); + Assert.assertTrue(wrapperQuery.getFieldWrapper(CommonData.defaultVectorField).getFieldData().size() >= 4); -} + } + + + } diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/search/RangeSearchTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/search/RangeSearchTest.java index f65464c09..2f7e457a9 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/search/RangeSearchTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/search/RangeSearchTest.java @@ -189,8 +189,8 @@ public void rangeSearchIPWithRangeFilterLessThanRadius(){ .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) .build(); R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); - Assert.assertTrue(searchResultsR.getException().getMessage().contains("range_filter > radius")); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 1100); + Assert.assertTrue(searchResultsR.getException().getMessage().contains("range_filter must be greater than radius")); } @@ -259,7 +259,7 @@ public void rangeSearchL2WithRangeFilter(){ .withMetricType(MetricType.L2) .withOutFields(search_output_fields) .withTopK(SEARCH_K) - .withVectors(searchVectorsL2) + .withFloatVectors(searchVectorsL2) .withVectorFieldName(CommonData.defaultVectorField) .withParams(SEARCH_PARAM) .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) @@ -292,8 +292,8 @@ public void rangeSearchL2WithRangeFilterLargeThanRadius(){ .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) .build(); R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); - Assert.assertTrue(searchResultsR.getException().getMessage().contains("range_filter < radius")); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 1100); + Assert.assertTrue(searchResultsR.getException().getMessage().contains("range_filter must be less than radius")); } diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/search/SearchIteratorTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/search/SearchIteratorTest.java new file mode 100644 index 000000000..c8b592793 --- /dev/null +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/search/SearchIteratorTest.java @@ -0,0 +1,201 @@ +package com.zilliz.milvustest.search; + +import com.google.common.collect.Lists; +import com.zilliz.milvustest.common.BaseTest; +import com.zilliz.milvustest.common.CommonData; +import com.zilliz.milvustest.common.CommonFunction; +import io.milvus.common.clientenum.ConsistencyLevelEnum; +import io.milvus.grpc.MutationResult; +import io.milvus.grpc.SearchResults; +import io.milvus.orm.iterator.SearchIterator; +import io.milvus.param.IndexType; +import io.milvus.param.MetricType; +import io.milvus.param.R; +import io.milvus.param.collection.DropCollectionParam; +import io.milvus.param.dml.InsertParam; +import io.milvus.param.dml.SearchIteratorParam; +import io.milvus.param.dml.ranker.RRFRanker; +import io.milvus.response.SearchResultsWrapper; +import io.qameta.allure.Epic; +import io.qameta.allure.Feature; +import org.testng.Assert; +import org.testng.annotations.AfterClass; +import org.testng.annotations.BeforeClass; +import org.testng.annotations.DataProvider; +import org.testng.annotations.Test; + +import java.time.LocalDateTime; +import java.util.List; + +/** + * @Author yongpeng.li + * @Date 2024/4/15 17:49 + */ +@Epic("Search") +@Feature("SearchIterator") +public class SearchIteratorTest extends BaseTest { + private String collectionWithFloatVector; + private String collectionWithBinaryVector; + private String collectionWithSparseVector; + + private String collectionWithFloat16Vector; + private String collectionWithBF16Vector; + + @BeforeClass(alwaysRun = true) + public void provideTestData() { + collectionWithFloatVector = CommonFunction.createNewCollection(); + CommonFunction.insertDataIntoCollection(collectionWithFloatVector, null, 10000); + CommonFunction.createIndexWithLoad(collectionWithFloatVector, IndexType.HNSW, MetricType.L2, CommonData.defaultVectorField); + + collectionWithBinaryVector = CommonFunction.createBinaryCollection(); + CommonFunction.insertDataIntoCollection(collectionWithBinaryVector, CommonFunction.generateBinaryData(10000)); + CommonFunction.createIndexWithLoad(collectionWithBinaryVector, IndexType.BIN_FLAT, MetricType.HAMMING, CommonData.defaultBinaryVectorField); + + collectionWithSparseVector = CommonFunction.createSparseFloatVectorCollection(); + CommonFunction.insertDataIntoCollection(collectionWithSparseVector, CommonFunction.generateDataWithSparseFloatVector(100000)); + CommonFunction.createIndexWithLoad(collectionWithSparseVector, IndexType.SPARSE_INVERTED_INDEX, MetricType.IP, CommonData.defaultSparseVectorField); + + + collectionWithFloat16Vector = CommonFunction.createFloat16Collection(); + CommonFunction.insertDataIntoCollection(collectionWithFloat16Vector,CommonFunction.generateDataWithFloat16Vector(10000)); + CommonFunction.createIndexWithLoad(collectionWithFloat16Vector,IndexType.HNSW,MetricType.IP,CommonData.defaultFloat16VectorField); + + collectionWithBF16Vector = CommonFunction.createBf16Collection(); + CommonFunction.insertDataIntoCollection(collectionWithBF16Vector,CommonFunction.generateDataWithBF16Vector(10000)); + CommonFunction.createIndexWithLoad(collectionWithBF16Vector,IndexType.HNSW,MetricType.L2,CommonData.defaultBF16VectorField); + + } + + @AfterClass(alwaysRun = true) + public void cleanTestData() { + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithFloatVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithSparseVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithBinaryVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithFloat16Vector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithBF16Vector).build()); + } + + @DataProvider(name = "testData") // nq,topK,batchSize,expected1,expect2 + public Object[][] provideDataWithExpect(){ + return new Object[][]{ + {1,1,10L,1,0}, + {1,50,50L,50,0}, + {1,50,10L,10,10}, + {1,50,10000L,50,0} + }; + } + + //nq: 1.Not support search iteration over multiple vectors at present + @Test(description = "Search Iterator by float vector collection",groups = {"Smoke"},dataProvider = "testData") + public void searchIterator(int nq,int topK,long bachSize,int expected1,int expected2) { + R searchIteratorR = milvusClient.searchIterator(SearchIteratorParam.newBuilder() + .withCollectionName(collectionWithFloatVector) + .withMetricType(MetricType.L2) + .withOutFields(Lists.newArrayList("*")) + .withTopK(topK) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) + .withBatchSize(bachSize) + .withFloatVectors(Lists.newArrayList(CommonFunction.generateFloatVectors(nq, CommonData.dim))) + .build()); + Assert.assertEquals(searchIteratorR.getStatus().intValue(), 0); + Assert.assertEquals(searchIteratorR.getData().next().size(),expected1); + Assert.assertEquals(searchIteratorR.getData().next().size(),expected2); + } + + @Test(description = "Search Iterator by binary vector collection",groups = {"Smoke"},dataProvider = "testData") + public void searchIteratorByBinaryVector(int nq,int topK,long batchSize,int expected1,int expected2) { + long start = System.currentTimeMillis(); + R searchIteratorR = milvusClient.searchIterator(SearchIteratorParam.newBuilder() + .withCollectionName(collectionWithBinaryVector) + .withMetricType(MetricType.JACCARD) + .withOutFields(Lists.newArrayList("*")) + .withTopK(topK) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.BIN_FLAT)) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .withBatchSize(batchSize) + .withBinaryVectors(Lists.newArrayList(CommonFunction.generateBinaryVectors(nq, CommonData.dim))) + .build()); + long end = System.currentTimeMillis(); + System.out.println("cost:"+(end-start)/1000.0); + Assert.assertEquals(searchIteratorR.getStatus().intValue(), 0); + Assert.assertEquals(searchIteratorR.getData().next().size(),expected1); + Assert.assertEquals(searchIteratorR.getData().next().size(),expected2); + } + + @Test(description = "Search Iterator by Sparse vector collection",groups = {"Smoke"},dataProvider = "testData") + public void searchIteratorBySparseVector(int nq,int topK,long batchSize,int expected1,int expected2) { + long start = System.currentTimeMillis(); + R searchIteratorR = milvusClient.searchIterator(SearchIteratorParam.newBuilder() + .withCollectionName(collectionWithSparseVector) + .withMetricType(MetricType.IP) + .withOutFields(Lists.newArrayList("*")) + .withTopK(topK) + .withVectorFieldName(CommonData.defaultSparseVectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.SPARSE_INVERTED_INDEX)) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .withBatchSize(batchSize) + .withSparseFloatVectors(Lists.newArrayList(CommonFunction.generateSparseVector())) + .build()); + long end = System.currentTimeMillis(); + System.out.println("cost:"+(end-start)/1000.0); + Assert.assertEquals(searchIteratorR.getStatus().intValue(), 0); + Assert.assertEquals(searchIteratorR.getData().next().size(),expected1); + Assert.assertEquals(searchIteratorR.getData().next().size(),expected2); + } + + + @Test(description = "Search Iterator by float16 vector collection",groups = {"Smoke"},dataProvider = "testData") + public void searchIteratorByFloat16Vector(int nq,int topK,long batchSize,int expected1,int expected2) { + long start = System.currentTimeMillis(); + R searchIteratorR = milvusClient.searchIterator(SearchIteratorParam.newBuilder() + .withCollectionName(collectionWithFloat16Vector) + .withMetricType(MetricType.IP) + .withOutFields(Lists.newArrayList("*")) + .withTopK(topK) + .withVectorFieldName(CommonData.defaultFloat16VectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .withBatchSize(batchSize) + .withFloat16Vectors(Lists.newArrayList(CommonFunction.generateFloat16Vectors(CommonData.dim,nq))) + .build()); + long end = System.currentTimeMillis(); + System.out.println("cost:"+(end-start)/1000.0); + Assert.assertEquals(searchIteratorR.getStatus().intValue(), 0); + Assert.assertEquals(searchIteratorR.getData().next().size(),expected1); + Assert.assertEquals(searchIteratorR.getData().next().size(),expected2); + } + + @Test(description = "Search Iterator by bf16 vector collection",groups = {"Smoke"},dataProvider = "testData") + public void searchIteratorByBF16Vector(int nq,int topK,long batchSize,int expected1,int expected2) { + long start = System.currentTimeMillis(); + R searchIteratorR = milvusClient.searchIterator(SearchIteratorParam.newBuilder() + .withCollectionName(collectionWithBF16Vector) + .withMetricType(MetricType.L2) + .withOutFields(Lists.newArrayList("*")) + .withTopK(topK) + .withVectorFieldName(CommonData.defaultBF16VectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .withBatchSize(batchSize) + .withBFloat16Vectors(Lists.newArrayList(CommonFunction.generateBF16Vectors(CommonData.dim,nq))) + .build()); + long end = System.currentTimeMillis(); + System.out.println("cost:"+(end-start)/1000.0); + Assert.assertEquals(searchIteratorR.getStatus().intValue(), 0); + Assert.assertEquals(searchIteratorR.getData().next().size(),expected1); + Assert.assertEquals(searchIteratorR.getData().next().size(),expected2); + } + + + + + +} diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/search/SearchTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/search/SearchTest.java index 73c4f8ceb..501ac1b5a 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/search/SearchTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/search/SearchTest.java @@ -1,12 +1,14 @@ package com.zilliz.milvustest.search; import com.alibaba.fastjson.JSONObject; +import com.google.common.collect.Lists; import com.zilliz.milvustest.common.BaseTest; import com.zilliz.milvustest.common.CommonData; import com.zilliz.milvustest.common.CommonFunction; import com.zilliz.milvustest.util.MathUtil; import io.milvus.common.clientenum.ConsistencyLevelEnum; import io.milvus.exception.ParamException; +import io.milvus.grpc.GetCollectionStatisticsResponse; import io.milvus.grpc.MutationResult; import io.milvus.grpc.SearchResults; import io.milvus.param.IndexType; @@ -14,12 +16,13 @@ import io.milvus.param.R; import io.milvus.param.RpcStatus; import io.milvus.param.collection.DropCollectionParam; +import io.milvus.param.collection.GetCollectionStatisticsParam; import io.milvus.param.collection.LoadCollectionParam; import io.milvus.param.collection.ReleaseCollectionParam; -import io.milvus.param.dml.DeleteParam; -import io.milvus.param.dml.InsertParam; -import io.milvus.param.dml.SearchParam; +import io.milvus.param.dml.*; +import io.milvus.param.dml.ranker.RRFRanker; import io.milvus.param.index.CreateIndexParam; +import io.milvus.param.index.DropIndexParam; import io.milvus.response.FieldDataWrapper; import io.milvus.response.SearchResultsWrapper; import io.qameta.allure.*; @@ -30,1932 +33,2317 @@ import org.testng.annotations.Test; import java.nio.ByteBuffer; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Random; +import java.util.*; import static com.zilliz.milvustest.util.MathUtil.combine; @Epic("Search") @Feature("Search") public class SearchTest extends BaseTest { - public String newBookName; - public String newBookNameBin; - public String collectionWithJsonField; - public String collectionWithDynamicField; - - public String collectionWithArrayField; - - @BeforeClass(description = "load collection first",alwaysRun = true) - public void loadCollection() { - milvusClient.loadCollection( - LoadCollectionParam.newBuilder().withCollectionName(CommonData.defaultCollection).build()); - milvusClient.loadCollection( - LoadCollectionParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .build()); - milvusClient.loadCollection( - LoadCollectionParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .build()); - milvusClient.loadCollection( - LoadCollectionParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKBinaryCollection) - .build()); - collectionWithJsonField= CommonFunction.createNewCollectionWithJSONField(); - collectionWithDynamicField= CommonFunction.createNewCollectionWithDynamicField(); - collectionWithArrayField= CommonFunction.createNewCollectionWithArrayField(); - } - - @DataProvider(name="dynamicExpressions") - public Object[][] provideDynamicExpression(){ - return new Object[][]{ - {"json_field[\"int32\"] in [2,4,6,8]"}, - {"book_id in [10,20,30,40]"}, - {"extra_field2 in [1,2,3,4]"}, - {"\"String0\"<=extra_field<=\"String3\""} - }; - } - @DataProvider(name="jsonExpressions") - public Object[][] provideJsonExpression(){ - return new Object[][]{ - {"int64_field in [10,20,30,40]"}, - {"json_field[\"int64_field\"] in [10,20,30,40]"}, - {"json_field[\"inner_json\"][\"int32\"] in [1,2,3,4]"}, - {"\"Str0\"<=json_field[\"inner_json\"][\"varchar\"]<=\"Str3\""}, - {"json_field[\"inner_json\"][\"int64\"] in [10,20,30,40]"} - }; - } - @AfterClass(description = "release collection after test",alwaysRun = true) - public void releaseCollection() { - milvusClient.releaseCollection( - ReleaseCollectionParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .build()); - milvusClient.releaseCollection( - ReleaseCollectionParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .build()); - milvusClient.releaseCollection( - ReleaseCollectionParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .build()); - milvusClient.releaseCollection( - ReleaseCollectionParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKBinaryCollection) - .build()); - milvusClient.dropCollection( - DropCollectionParam.newBuilder().withCollectionName(collectionWithJsonField).build()); - milvusClient.dropCollection( - DropCollectionParam.newBuilder().withCollectionName(collectionWithDynamicField).build()); - milvusClient.dropCollection( - DropCollectionParam.newBuilder().withCollectionName(collectionWithArrayField).build()); - - } - - @DataProvider(name = "providerPartition") - public Object[][] providerPartition() { - return new Object[][] {{Boolean.FALSE}, {Boolean.TRUE}}; - } - - @DataProvider(name = "providerConsistency") - public Object[][] providerConsistency() { - return new Object[][] { - {ConsistencyLevelEnum.STRONG}, - {ConsistencyLevelEnum.BOUNDED}, - {ConsistencyLevelEnum.EVENTUALLY} - }; - } - - @DataProvider(name = "IndexTypes") - public Object[][] provideIndexType() { - return new Object[][] { - {IndexType.IVF_FLAT}, - {IndexType.IVF_SQ8}, - {IndexType.IVF_PQ}, - {IndexType.HNSW}, - {IndexType.SCANN}, - {IndexType.GPU_IVF_FLAT}, - {IndexType.GPU_IVF_PQ} - }; - } - - @DataProvider(name = "MetricType") - public Object[][] providerMetricType() { - return new Object[][] {{MetricType.L2}, {MetricType.IP}}; - } - - @DataProvider(name = "FloatIndex") - public Object[][] providerIndexForFloatCollection() { - return combine(provideIndexType(), providerMetricType()); - } - - @DataProvider(name = "BinaryIndexTypes") - public Object[][] provideBinaryIndexType() { - return new Object[][] {{IndexType.BIN_IVF_FLAT}, {IndexType.BIN_FLAT}}; - } - - @DataProvider(name = "BinaryMetricType") - public Object[][] providerBinaryMetricType() { - return new Object[][] { - {MetricType.HAMMING}, - {MetricType.JACCARD} - }; - } - - @DataProvider(name = "BinaryIndex") - public Object[][] providerIndexForBinaryCollection() { - return combine(provideBinaryIndexType(), providerBinaryMetricType()); - } - - @DataProvider(name="provideIntExpressions") - public Object[][] provideIntExpression(){ - return new Object[][]{ - {"book_id > 10"}, - {"book_id >= 10"}, - {"book_id < 10"}, - {"book_id <= 10"}, - {"book_id == 10"}, - {"book_id !=10"}, - {"book_id in [10,20,30,40]"}, - {"book_id not in [10]"}, - {"10 < book_id < 50 "}, - {"50 > book_id > 10 "}, - {"10 <= book_id <=50 "}, - {"10 <= book_id <50 "}, - {"10 < book_id <=50 "}, - {"book_id >10 and word_count > 10010 "}, - {"book_id >10 and word_count >= 10110 "}, - {"book_id in [10,20,30,40] and word_count >= 10010 "}, - {"book_id not in [10,20,30,40] and word_count >= 10010 "}, - {"book_id in [10,20,30,40] and word_count in [10010,10020,10030,10040] "}, - {"book_id not in [10,20,30,40] and word_count not in [10010,10020,10030,10040] "} - - }; - } - @DataProvider(name="provideStringExpressions") - public Object[][] provideStringExpression(){ - return new Object[][]{ - {" book_name > \"10\" "}, - {" book_name > \"a\" "}, - {" book_name >= \"a\" "}, - {" book_name not in [\"a\"] "}, - {" book_name > book_content "}, - {" book_name >= book_content "}, - {" book_name < book_content "}, - {" book_name <= book_content "}, - {" \"10\" < book_name <= \"a\" "}, - {" \"a\" <= book_name < \"zAs\" "}, - {" \"asa\" < book_name <= \"zaa\" "}, - {" \"a\" <= book_name and book_name >= \"99\" "}, - {" book_name like \"国%\" "}, - {" book_name like \"国%\" and book_name >\"abc\" "}, - {" book_name like \"国%\" and book_content like\"1%\" "}, - {" book_name like \"国%\" and book_content > \"1\" "} - }; - } - - @Severity(SeverityLevel.BLOCKER) - @Test( - description = - "Conducts ANN search on a vector field. Use expression to do filtering before search.", - dataProvider = "providerPartition",groups = {"Smoke"}) - public void intPKAndFloatVectorSearch(Boolean usePart) { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultPartition) : Arrays.asList()) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).size(), 2); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.CRITICAL) - @Test(description = "Conduct a hybrid search", dataProvider = "providerPartition") - public void intPKAndFloatVectorHybridSearch(Boolean usePart) { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultPartition) : Arrays.asList()) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr(" book_id > 1000 ") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertTrue(searchResultsR.getData().getResults().getIds().getIntId().getData(0) > 1000); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.BLOCKER) - @Test(description = "Conduct a search with binary vector", dataProvider = "providerPartition") - public void intPKAndBinaryVectorSearch(Boolean usePart) { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List search_vectors = CommonFunction.generateBinaryVectors(1, 128); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultBinaryPartition) : Arrays.asList()) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - System.out.println(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsR.getData().getResults().getTopK(), 2); - Assert.assertEquals( - searchResultsR.getData().getResults().getIds().getIntId().getDataCount(), 2); - } - - @Severity(SeverityLevel.CRITICAL) - @Test(description = "Conduct a hybrid binary vector search", dataProvider = "providerPartition") - public void intPKAndBinaryVectorHybridSearch(Boolean usePart) { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List search_vectors = CommonFunction.generateBinaryVectors(1, 128); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultBinaryPartition) : Arrays.asList()) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .withExpr(" book_id > 1000 ") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - Assert.assertTrue(searchResultsR.getData().getResults().getIds().getIntId().getData(0) > 1000); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.BLOCKER) - @Test( - description = "Conduct float vector search with String PK", - dataProvider = "providerPartition") - public void stringPKAndFloatVectorSearch(Boolean usePart) { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultStringPKPartition) : Arrays.asList()) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).size(), 2); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.CRITICAL) - @Test( - description = "Conduct float vector search with String PK", - dataProvider = "providerPartition") - public void stringPKAndFloatVectorHybridSearch(Boolean usePart) { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultStringPKPartition) : Arrays.asList()) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr(" book_name like \"a%\" ") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).size(), 2); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.BLOCKER) - @Test( - description = "Conduct binary vector search with String PK", - dataProvider = "providerPartition") - public void stringPKAndBinaryVectorSearch(Boolean usePart) { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name"); - List search_vectors = CommonFunction.generateBinaryVectors(1, 128); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKBinaryCollection) - .withPartitionNames( - usePart - ? Arrays.asList(CommonData.defaultStringPKBinaryPartition) - : Arrays.asList()) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).size(), 2); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.CRITICAL) - @Test( - description = "Conduct binary vector search with String PK", - dataProvider = "providerPartition") - public void stringPKAndBinaryVectorHybridSearch(Boolean usePart) { - Integer SEARCH_K = 20; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name"); - List search_vectors = CommonFunction.generateBinaryVectors(1, 128); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKBinaryCollection) - .withPartitionNames( - usePart - ? Arrays.asList(CommonData.defaultStringPKBinaryPartition) - : Arrays.asList()) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .withExpr(" book_name like \"国%\" ") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals( - searchResultsWrapper.getFieldData("book_name", 0).size(), SEARCH_K.intValue()); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.NORMAL) - @Test(description = "search in nonexistent partition") - public void searchInNonexistentPartition() { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withPartitionNames(Arrays.asList("nonexistent")) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); - Assert.assertEquals( - searchResultsR.getException().getMessage(), "partition name nonexistent not found"); - System.out.println(searchResultsR); - } - - @Severity(SeverityLevel.NORMAL) - @Test(description = "search float vector with error vectors value)") - public void searchWithErrorVectors() { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(2))); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); - Assert.assertTrue(searchResultsR.getException().getMessage().contains("fail to search")); - System.out.println(searchResultsR.getException().getMessage()); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "search binary vector with error MetricType", - expectedExceptions = ParamException.class) - public void binarySearchWithErrorMetricType() { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List search_vectors = CommonFunction.generateBinaryVectors(1, 128); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .withMetricType(MetricType.IP) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .withExpr(" book_id > 1000 ") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); - Assert.assertTrue( - searchResultsR - .getException() - .getMessage() - .contains("binary search not support metric type: METRIC_INNER_PRODUCT")); - } - - @Severity(SeverityLevel.NORMAL) - @Test(description = "search with error MetricType", expectedExceptions = ParamException.class) - @Issue("https://github.com/milvus-io/milvus-sdk-java/issues/313") - public void SearchWithErrorMetricType() { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr(" book_id > 1000 ") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - Assert.assertTrue( - searchResultsR - .getException() - .getMessage() - .contains("binary search not support metric type: METRIC_INNER_JACCARD")); - } - - @Severity(SeverityLevel.MINOR) - @Test(description = "search with empty vector", expectedExceptions = ParamException.class) - public void searchWithEmptyVector() { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = new ArrayList<>(); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr(" book_id > 1000 ") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); - Assert.assertTrue( - searchResultsR.getException().getMessage().contains("Target vectors can not be empty")); - } - - @Severity(SeverityLevel.MINOR) - @Test(description = "binary search with empty vector", expectedExceptions = ParamException.class) - public void binarySearchWithEmptyVector() { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List search_vectors = new ArrayList<>(); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .withExpr(" book_id > 1000 ") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); - Assert.assertTrue( - searchResultsR.getException().getMessage().contains("Target vectors can not be empty")); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "int PK and float vector search after insert the entity", - dataProvider = "providerPartition") - public void intPKAndFloatVectorSearchAfterInsertNewEntity(Boolean usePart) - throws InterruptedException { - // insert entity first - List book_id_array = - new ArrayList() { - { - add(9999L); - } - }; - List word_count_array = - new ArrayList() { - { - add(19999L); - } - }; - List fs = Arrays.asList(MathUtil.generateFloat(128)); - List> book_intro_array = - new ArrayList>() { - { - add(fs); - } - }; - List fields = new ArrayList<>(); - fields.add(new InsertParam.Field("book_id", book_id_array)); - fields.add(new InsertParam.Field("word_count", word_count_array)); - fields.add( - new InsertParam.Field( - CommonData.defaultVectorField, book_intro_array)); - milvusClient.insert( - InsertParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withPartitionName(usePart ? CommonData.defaultPartition : "") - .withFields(fields) - .build()); - Thread.sleep(2000); - // search - Integer SEARCH_K = 1; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id", "word_count"); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultPartition) : Arrays.asList()) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(book_intro_array) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr("book_id == 9999") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("word_count", 0).get(0), 19999L); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).get(0), 9999L); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "int PK and binary vector search after insert the entity", - dataProvider = "providerPartition") - public void intPKAndBinaryVectorSearchAfterInsertNewEntity(Boolean usePart) - throws InterruptedException { - // insert entity first - List book_id_array = - new ArrayList() { - { - add(9999L); - } - }; - List word_count_array = - new ArrayList() { - { - add(19999L); - } - }; - List book_intro_array = CommonFunction.generateBinaryVectors(1, 128); - - List fields = new ArrayList<>(); - fields.add(new InsertParam.Field("book_id", book_id_array)); - fields.add(new InsertParam.Field("word_count", word_count_array)); - fields.add( - new InsertParam.Field( - CommonData.defaultBinaryVectorField, book_intro_array)); - milvusClient.insert( - InsertParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .withPartitionName(usePart ? CommonData.defaultBinaryPartition : "") - .withFields(fields) - .build()); - Thread.sleep(2000); - // search - Integer SEARCH_K = 1; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id", "word_count"); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultBinaryPartition) : Arrays.asList()) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(book_intro_array) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .withConsistencyLevel(ConsistencyLevelEnum.STRONG) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("word_count", 0).get(0), 19999L); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).get(0), 9999L); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "string PK and float vector search after insert the entity", - dataProvider = "providerPartition") - public void stringPKAndFloatVectorSearchAfterInsertNewEntity(Boolean usePart) - throws InterruptedException { - // insert entity first - newBookName = MathUtil.genRandomStringAndChinese(10); - String newBookContent = MathUtil.genRandomStringAndChinese(20); - System.out.println("newBookContent:" + newBookContent); - List book_name_array = - new ArrayList() { - { - add(newBookName); - } - }; - List book_content_array = - new ArrayList() { - { - add(newBookContent); - } - }; - List fs = Arrays.asList(MathUtil.generateFloat(128)); - List> book_intro_array = - new ArrayList>() { - { - add(fs); - } - }; - List fields = new ArrayList<>(); - fields.add(new InsertParam.Field("book_name", book_name_array)); - fields.add(new InsertParam.Field("book_content", book_content_array)); - fields.add( - new InsertParam.Field( - CommonData.defaultVectorField, book_intro_array)); - milvusClient.insert( - InsertParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withPartitionName(usePart ? CommonData.defaultStringPKPartition : "") - .withFields(fields) - .build()); - Thread.sleep(2000); - // search - Integer SEARCH_K = 1; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name", "book_content"); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultStringPKPartition) : Arrays.asList()) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(book_intro_array) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr("book_name == \"" + newBookName + "\"") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals( - searchResultsWrapper.getFieldData("book_content", 0).get(0), newBookContent); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).get(0), newBookName); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "string PK and binary vector search after insert the entity", - dataProvider = "providerPartition") - public void stringPKAndBinaryVectorSearchAfterInsertNewEntity(Boolean usePart) - throws InterruptedException { - // insert entity first - newBookNameBin = MathUtil.genRandomStringAndChinese(10); - String newBookContent = MathUtil.genRandomStringAndChinese(20); - List book_name_array = - new ArrayList() { - { - add(newBookNameBin); - } - }; - List book_content_array = - new ArrayList() { - { - add(newBookContent); - } - }; - List book_intro_array = CommonFunction.generateBinaryVectors(1, 128); - List fields = new ArrayList<>(); - fields.add(new InsertParam.Field("book_name", book_name_array)); - fields.add(new InsertParam.Field("book_content", book_content_array)); - fields.add( - new InsertParam.Field( - CommonData.defaultBinaryVectorField, book_intro_array)); - milvusClient.insert( - InsertParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKBinaryCollection) - .withPartitionName(usePart ? CommonData.defaultStringPKBinaryPartition : "") - .withFields(fields) - .build()); - Thread.sleep(2000); - // search - Integer SEARCH_K = 1; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name", "book_content"); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKBinaryCollection) - .withPartitionNames( - usePart - ? Arrays.asList(CommonData.defaultStringPKBinaryPartition) - : Arrays.asList()) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(book_intro_array) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .withExpr("book_name == \"" + newBookNameBin + "\"") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals( - searchResultsWrapper.getFieldData("book_content", 0).get(0), newBookContent); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).get(0), newBookNameBin); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "int PK and float vector search after update the entity", - dataProvider = "providerPartition") - public void intPKAndFloatVectorSearchAfterUpdateEntity(Boolean usePart) - throws InterruptedException { - Random random = new Random(); - int id = random.nextInt(2000); - // update entity first - List book_id_array = - new ArrayList() { - { - add((long) id); - } - }; - List word_count_array = - new ArrayList() { - { - add(19999L); - } - }; - List fs = Arrays.asList(MathUtil.generateFloat(128)); - List> book_intro_array = - new ArrayList>() { - { - add(fs); - } + private String newBookName; + private String newBookNameBin; + private String collectionWithJsonField; + private String collectionWithDynamicField; + + private String collectionWithArrayField; + + private String collectionWithFloat16Vector; + private String collectionWithBf16Vector; + + private String collectionWithSparseVector; + + private String collectionWithMultiVector; + private String collectionWithFloatVector; + private String collectionWithBinaryVector; + + @BeforeClass(description = "load collection first", alwaysRun = true) + public void loadCollection() { + milvusClient.loadCollection( + LoadCollectionParam.newBuilder().withCollectionName(CommonData.defaultCollection).build()); + milvusClient.loadCollection( + LoadCollectionParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .build()); + milvusClient.loadCollection( + LoadCollectionParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .build()); + milvusClient.loadCollection( + LoadCollectionParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKBinaryCollection) + .build()); + collectionWithJsonField = CommonFunction.createNewCollectionWithJSONField(); + collectionWithDynamicField = CommonFunction.createNewCollectionWithDynamicField(); + collectionWithArrayField = CommonFunction.createNewCollectionWithArrayField(); + + collectionWithFloat16Vector = CommonFunction.createFloat16Collection(); + List fields = CommonFunction.generateDataWithFloat16Vector(2000); + milvusClient.insert(InsertParam.newBuilder() + .withFields(fields) + .withCollectionName(collectionWithFloat16Vector) + .build()); + CommonFunction.createIndexWithLoad(collectionWithFloat16Vector, IndexType.HNSW, MetricType.L2, CommonData.defaultFloat16VectorField); + + collectionWithBf16Vector = CommonFunction.createBf16Collection(); + List bf16Fields = CommonFunction.generateDataWithBF16Vector(10000); + milvusClient.insert(InsertParam.newBuilder() + .withFields(bf16Fields) + .withCollectionName(collectionWithBf16Vector) + .build()); + CommonFunction.createIndexWithLoad(collectionWithBf16Vector, IndexType.HNSW, MetricType.L2, CommonData.defaultBF16VectorField); + + collectionWithSparseVector = CommonFunction.createSparseFloatVectorCollection(); + List sparseFields = CommonFunction.generateDataWithSparseFloatVector(100000); + milvusClient.insert(InsertParam.newBuilder() + .withFields(sparseFields) + .withCollectionName(collectionWithSparseVector) + .build()); + CommonFunction.createIndexWithLoad(collectionWithSparseVector, IndexType.SPARSE_INVERTED_INDEX, MetricType.IP, CommonData.defaultSparseVectorField); + + collectionWithMultiVector = CommonFunction.createMultiVectorCollection(); + List multiFields = CommonFunction.generateDataWithMultiVector(10000); + milvusClient.insert(InsertParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withFields(multiFields) + .build()); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.HNSW, MetricType.L2, CommonData.defaultVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.BIN_FLAT, MetricType.HAMMING, CommonData.defaultBinaryVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.SPARSE_INVERTED_INDEX, MetricType.IP, CommonData.defaultSparseVectorField); + CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.HNSW, MetricType.L2, CommonData.defaultFloat16VectorField); +// CommonFunction.createIndexWithoutLoad(collectionWithMultiVector, IndexType.HNSW, MetricType.L2, CommonData.defaultBF16VectorField); + milvusClient.loadCollection(LoadCollectionParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withSyncLoad(true).build()); + + collectionWithFloatVector = CommonFunction.createNewCollection(); + CommonFunction.insertDataIntoCollection(collectionWithFloatVector, null, 10000); + CommonFunction.createIndexWithLoad(collectionWithFloatVector, IndexType.HNSW, MetricType.L2, CommonData.defaultVectorField); + + collectionWithBinaryVector = CommonFunction.createBinaryCollection(); + CommonFunction.insertDataIntoCollection(collectionWithBinaryVector, CommonFunction.generateBinaryData(10000)); + CommonFunction.createIndexWithLoad(collectionWithBinaryVector, IndexType.BIN_FLAT, MetricType.HAMMING, CommonData.defaultBinaryVectorField); + + } + + @DataProvider(name = "dynamicExpressions") + public Object[][] provideDynamicExpression() { + return new Object[][]{ + {"json_field[\"int32\"] in [2,4,6,8]"}, + {"book_id in [10,20,30,40]"}, + {"extra_field2 in [1,2,3,4]"}, + {"\"String0\"<=extra_field<=\"String3\""} }; - List fields = new ArrayList<>(); - fields.add(new InsertParam.Field("book_id", book_id_array)); - fields.add(new InsertParam.Field("word_count", word_count_array)); - fields.add( - new InsertParam.Field( - CommonData.defaultVectorField, book_intro_array)); - milvusClient.insert( - InsertParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withPartitionName(usePart ? CommonData.defaultPartition : "") - .withFields(fields) - .build()); - Thread.sleep(2000); - // search - Integer SEARCH_K = 1; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id", "word_count"); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultPartition) : Arrays.asList()) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(book_intro_array) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr("book_id == "+id) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("word_count", 0).get(0), 19999L); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "int PK and binary vector search after update the entity", - dataProvider = "providerPartition") - public void intPKAndBinaryVectorSearchAfterUpdateEntity(Boolean usePart) - throws InterruptedException { - Random random = new Random(); - int id = random.nextInt(2000); - // update entity first - List book_id_array = - new ArrayList() { - { - add((long) id); - } + } + + @DataProvider(name = "jsonExpressions") // expr,topK,expected + public Object[][] provideJsonExpression() { + return new Object[][]{ + {"int64_field in [10,20,30,40]", 10, 4}, + {"json_field[\"int64_field\"] in [10,20,30,40]", 10, 4}, + {"json_field[\"inner_json\"][\"int32\"] in [1,2,3,4]", 10, 4}, + {"\"Str0\"<=json_field[\"inner_json\"][\"varchar\"]<=\"Str3\"", 10, 10}, + {"json_field[\"inner_json\"][\"int64\"] in [10,20,30,40]", 10, 4}, + {"json_field[\"bool\"]==true", 10, 10}, + {"json_field[\"inner_json\"][\"bool\"]==true", 10, 10}, + {"json_field[\"inner_json\"][\"bool\"]==1", 10, 0}, + {"json_field[\"inner_json\"][\"bool\"]>1", 10, 0}, + {"json_field[\"string_field\"] == \"Str0\"", 10, 1}, + {"json_field[\"inner_json\"][\"varchar\"] == \"Str0\"", 10, 1}, + {"json_field[\"inner_json\"][\"varchar\"] like \"Str%\"", 10, 10}, + {"json_field[\"inner_json\"][\"varchar\"] like \"%Str\"", 10, 0}, + {"json_field[\"inner_json\"][\"varchar\"] like \"%Str%\"", 10, 10}, + {"json_field[\"array_field\"][0]==1", 10, 1}, + {"string_field in [\"Str0\",\"Str1\",\"Str2\",\"Str3\"]",10,4}, + {"json_field[\"array_field\"][0] in [1,2,3,4]", 10, 4}, + + }; - List word_count_array = - new ArrayList() { - { - add(19999L); - } + } + + @DataProvider(name = "sparseIndex") + public Object[][] provideSparseIndex() { + return new IndexType[][]{ + {IndexType.SPARSE_INVERTED_INDEX} + , {IndexType.SPARSE_WAND} }; - List book_intro_array = CommonFunction.generateBinaryVectors(1, 128); - - List fields = new ArrayList<>(); - fields.add(new InsertParam.Field("book_id", book_id_array)); - fields.add(new InsertParam.Field("word_count", word_count_array)); - fields.add( - new InsertParam.Field( - CommonData.defaultBinaryVectorField, book_intro_array)); - milvusClient.insert( - InsertParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .withPartitionName(usePart ? CommonData.defaultBinaryPartition : "") - .withFields(fields) - .build()); - Thread.sleep(2000); - // search - Integer SEARCH_K = 1; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id", "word_count"); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultBinaryPartition) : Arrays.asList()) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(book_intro_array) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("word_count", 0).get(0), 19999L); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "string PK and float vector search after update the entity", - dataProvider = "providerPartition", - dependsOnMethods = "stringPKAndFloatVectorSearchAfterInsertNewEntity") - public void stringPKAndFloatVectorSearchAfterUpdateNewEntity(Boolean usePart) - throws InterruptedException { - // delete entity first - milvusClient.delete( - DeleteParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withPartitionName(usePart ? CommonData.defaultStringPKPartition : "") - .withExpr("book_name in [\"" + newBookName + "\"]") - .build()); - Thread.sleep(4000); - // update entity first - String newBookContent = MathUtil.genRandomStringAndChinese(20); - System.out.println("newBookContent:" + newBookContent); - List book_name_array = - new ArrayList() { - { - add(newBookName); - } + } + + @AfterClass(description = "release collection after test", alwaysRun = true) + public void releaseCollection() { + milvusClient.releaseCollection( + ReleaseCollectionParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .build()); + milvusClient.releaseCollection( + ReleaseCollectionParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .build()); + milvusClient.releaseCollection( + ReleaseCollectionParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .build()); + milvusClient.releaseCollection( + ReleaseCollectionParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKBinaryCollection) + .build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithJsonField).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithDynamicField).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithArrayField).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithFloat16Vector).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithBf16Vector).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithSparseVector).build()); + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(collectionWithMultiVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithFloatVector).build()); + milvusClient.dropCollection(DropCollectionParam.newBuilder() + .withCollectionName(collectionWithSparseVector).build()); + } + + @DataProvider(name = "providerPartition") + public Object[][] providerPartition() { + return new Object[][]{{Boolean.FALSE}, {Boolean.TRUE}}; + } + + @DataProvider(name = "providerConsistency") + public Object[][] providerConsistency() { + return new Object[][]{ + {ConsistencyLevelEnum.STRONG}, + {ConsistencyLevelEnum.BOUNDED}, + {ConsistencyLevelEnum.EVENTUALLY} }; - List book_content_array = - new ArrayList() { - { - add(newBookContent); - } + } + + @DataProvider(name = "IndexTypes") + public Object[][] provideIndexType() { + return new Object[][]{ + {IndexType.IVF_FLAT}, + {IndexType.IVF_SQ8}, + {IndexType.IVF_PQ}, + {IndexType.HNSW}, + {IndexType.SCANN}, + {IndexType.GPU_IVF_FLAT}, + {IndexType.GPU_IVF_PQ} }; - List fs = Arrays.asList(MathUtil.generateFloat(128)); - List> book_intro_array = - new ArrayList>() { - { - add(fs); - } + } + + @DataProvider(name = "MetricType") + public Object[][] providerMetricType() { + return new Object[][]{{MetricType.L2}, {MetricType.IP}}; + } + + @DataProvider(name = "FloatIndex") + public Object[][] providerIndexForFloatCollection() { + return combine(provideIndexType(), providerMetricType()); + } + + @DataProvider(name = "BinaryIndexTypes") + public Object[][] provideBinaryIndexType() { + return new Object[][]{{IndexType.BIN_IVF_FLAT}, {IndexType.BIN_FLAT}}; + } + + @DataProvider(name = "BinaryMetricType") + public Object[][] providerBinaryMetricType() { + return new Object[][]{ + {MetricType.HAMMING}, + {MetricType.JACCARD} }; - List fields = new ArrayList<>(); - fields.add(new InsertParam.Field("book_name", book_name_array)); - fields.add(new InsertParam.Field("book_content", book_content_array)); - fields.add( - new InsertParam.Field( - CommonData.defaultVectorField, book_intro_array)); - milvusClient.insert( - InsertParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withPartitionName(usePart ? CommonData.defaultStringPKPartition : "") - .withFields(fields) - .build()); - Thread.sleep(2000); - // search - Integer SEARCH_K = 1; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name", "book_content"); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultStringPKPartition) : Arrays.asList()) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(book_intro_array) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withConsistencyLevel(ConsistencyLevelEnum.STRONG) - .withExpr("book_name == \"" + newBookName + "\"") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals( - searchResultsWrapper.getFieldData("book_content", 0).get(0), newBookContent); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).get(0), newBookName); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "string PK and float vector search after update the entity", - dataProvider = "providerPartition", - dependsOnMethods = "stringPKAndBinaryVectorSearchAfterInsertNewEntity") - public void stringPKAndBinaryVectorSearchAfterUpdateNewEntity(Boolean usePart) - throws InterruptedException { - // delete entity first - milvusClient.delete( - DeleteParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKBinaryCollection) - .withPartitionName(usePart ? CommonData.defaultStringPKBinaryPartition : "") - .withExpr("book_name in [\"" + newBookNameBin + "\"]") - .build()); - Thread.sleep(2000); - // insert entity first - String newBookContent = MathUtil.genRandomStringAndChinese(20); - List book_name_array = - new ArrayList() { - { - add(newBookNameBin); - } + } + + @DataProvider(name = "BinaryIndex") + public Object[][] providerIndexForBinaryCollection() { + return combine(provideBinaryIndexType(), providerBinaryMetricType()); + } + + @DataProvider(name = "provideIntExpressions") + public Object[][] provideIntExpression() { + return new Object[][]{ + {"book_id > 10"}, + {"book_id >= 10"}, + {"book_id < 10"}, + {"book_id <= 10"}, + {"book_id == 10"}, + {"book_id !=10"}, + {"book_id in [10,20,30,40]"}, + {"book_id not in [10]"}, + {"10 < book_id < 50 "}, + {"50 > book_id > 10 "}, + {"10 <= book_id <=50 "}, + {"10 <= book_id <50 "}, + {"10 < book_id <=50 "}, + {"book_id >10 and word_count > 10010 "}, + {"book_id >10 and word_count >= 10110 "}, + {"book_id in [10,20,30,40] and word_count >= 10010 "}, + {"book_id not in [10,20,30,40] and word_count >= 10010 "}, + {"book_id in [10,20,30,40] and word_count in [10010,10020,10030,10040] "}, + {"book_id not in [10,20,30,40] and word_count not in [10010,10020,10030,10040] "} + }; - List book_content_array = - new ArrayList() { - { - add(newBookContent); - } + } + + @DataProvider(name = "provideStringExpressions") + public Object[][] provideStringExpression() { + return new Object[][]{ + {" book_name > \"10\" "}, + {" book_name > \"a\" "}, + {" book_name >= \"a\" "}, + {" book_name not in [\"a\"] "}, + {" book_name > book_content "}, + {" book_name >= book_content "}, + {" book_name < book_content "}, + {" book_name <= book_content "}, + {" \"10\" < book_name <= \"a\" "}, + {" \"a\" <= book_name < \"zAs\" "}, + {" \"asa\" < book_name <= \"zaa\" "}, + {" \"a\" <= book_name and book_name >= \"99\" "}, + {" book_name like \"国%\" "}, + {" book_name like \"国%\" and book_name >\"abc\" "}, + {" book_name like \"国%\" and book_content like\"1%\" "}, + {" book_name like \"国%\" and book_content > \"1\" "} }; - List book_intro_array = CommonFunction.generateBinaryVectors(1, 128); - List fields = new ArrayList<>(); - fields.add(new InsertParam.Field("book_name", book_name_array)); - fields.add(new InsertParam.Field("book_content", book_content_array)); - fields.add( - new InsertParam.Field( - CommonData.defaultBinaryVectorField, book_intro_array)); - milvusClient.insert( - InsertParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKBinaryCollection) - .withPartitionName(usePart ? CommonData.defaultStringPKBinaryPartition : "") - .withFields(fields) - .build()); - Thread.sleep(2000); - // search - Integer SEARCH_K = 1; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name", "book_content"); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKBinaryCollection) - .withPartitionNames( - usePart - ? Arrays.asList(CommonData.defaultStringPKBinaryPartition) - : Arrays.asList()) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(book_intro_array) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .withConsistencyLevel(ConsistencyLevelEnum.STRONG) - .withExpr("book_name == \"" + newBookNameBin + "\"") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals( - searchResultsWrapper.getFieldData("book_content", 0).get(0), newBookContent); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).get(0), newBookNameBin); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "int PK and float vector search after delete data", - dataProvider = "providerPartition") - public void intPKAndFloatVectorSearchAfterDelete(Boolean usePart) throws InterruptedException { - R mutationResultR = + } + + @Severity(SeverityLevel.BLOCKER) + @Test( + description = + "Conducts ANN search on a vector field. Use expression to do filtering before search.", + dataProvider = "providerPartition", groups = {"Smoke"}) + public void intPKAndFloatVectorSearch(Boolean usePart) { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultPartition) : Arrays.asList()) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).size(), 2); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.CRITICAL) + @Test(description = "Conduct a hybrid search", dataProvider = "providerPartition") + public void intPKAndFloatVectorHybridSearch(Boolean usePart) { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultPartition) : Arrays.asList()) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr(" book_id > 1000 ") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertTrue(searchResultsR.getData().getResults().getIds().getIntId().getData(0) > 1000); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.BLOCKER) + @Test(description = "Conduct a search with binary vector", dataProvider = "providerPartition") + public void intPKAndBinaryVectorSearch(Boolean usePart) { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List search_vectors = CommonFunction.generateBinaryVectors(1, 128); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultBinaryPartition) : Arrays.asList()) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(search_vectors) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + System.out.println(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsR.getData().getResults().getTopK(), 2); + Assert.assertEquals( + searchResultsR.getData().getResults().getIds().getIntId().getDataCount(), 2); + } + + @Severity(SeverityLevel.CRITICAL) + @Test(description = "Conduct a hybrid binary vector search", dataProvider = "providerPartition") + public void intPKAndBinaryVectorHybridSearch(Boolean usePart) { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List search_vectors = CommonFunction.generateBinaryVectors(1, 128); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultBinaryPartition) : Arrays.asList()) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(search_vectors) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .withExpr(" book_id > 1000 ") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + Assert.assertTrue(searchResultsR.getData().getResults().getIds().getIntId().getData(0) > 1000); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.BLOCKER) + @Test( + description = "Conduct float vector search with String PK", + dataProvider = "providerPartition") + public void stringPKAndFloatVectorSearch(Boolean usePart) { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultStringPKPartition) : Arrays.asList()) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).size(), 2); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.CRITICAL) + @Test( + description = "Conduct float vector search with String PK", + dataProvider = "providerPartition") + public void stringPKAndFloatVectorHybridSearch(Boolean usePart) { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultStringPKPartition) : Arrays.asList()) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr(" book_name like \"a%\" ") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).size(), 2); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.BLOCKER) + @Test( + description = "Conduct binary vector search with String PK", + dataProvider = "providerPartition") + public void stringPKAndBinaryVectorSearch(Boolean usePart) { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name"); + List search_vectors = CommonFunction.generateBinaryVectors(1, 128); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKBinaryCollection) + .withPartitionNames( + usePart + ? Arrays.asList(CommonData.defaultStringPKBinaryPartition) + : Arrays.asList()) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(search_vectors) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).size(), 2); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.CRITICAL) + @Test( + description = "Conduct binary vector search with String PK", + dataProvider = "providerPartition") + public void stringPKAndBinaryVectorHybridSearch(Boolean usePart) { + Integer SEARCH_K = 20; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name"); + List search_vectors = CommonFunction.generateBinaryVectors(1, 128); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKBinaryCollection) + .withPartitionNames( + usePart + ? Arrays.asList(CommonData.defaultStringPKBinaryPartition) + : Arrays.asList()) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(search_vectors) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .withExpr(" book_name like \"国%\" ") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals( + searchResultsWrapper.getFieldData("book_name", 0).size(), SEARCH_K.intValue()); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.NORMAL) + @Test(description = "search in nonexistent partition") + public void searchInNonexistentPartition() { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withPartitionNames(Arrays.asList("nonexistent")) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); + Assert.assertEquals( + searchResultsR.getException().getMessage(), "partition name nonexistent not found"); + System.out.println(searchResultsR); + } + + @Severity(SeverityLevel.NORMAL) + @Test(description = "search float vector with error vectors value)") + public void searchWithErrorVectors() { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(2))); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); + Assert.assertTrue(searchResultsR.getException().getMessage().contains("fail to search")); + System.out.println(searchResultsR.getException().getMessage()); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "search binary vector with error MetricType", + expectedExceptions = ParamException.class) + public void binarySearchWithErrorMetricType() { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List search_vectors = CommonFunction.generateBinaryVectors(1, 128); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .withMetricType(MetricType.IP) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(search_vectors) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .withExpr(" book_id > 1000 ") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); + Assert.assertTrue( + searchResultsR + .getException() + .getMessage() + .contains("binary search not support metric type: METRIC_INNER_PRODUCT")); + } + + @Severity(SeverityLevel.NORMAL) + @Test(description = "search with error MetricType", expectedExceptions = ParamException.class) + @Issue("https://github.com/milvus-io/milvus-sdk-java/issues/313") + public void SearchWithErrorMetricType() { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr(" book_id > 1000 ") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + Assert.assertTrue( + searchResultsR + .getException() + .getMessage() + .contains("binary search not support metric type: METRIC_INNER_JACCARD")); + } + + @Severity(SeverityLevel.MINOR) + @Test(description = "search with empty vector", expectedExceptions = ParamException.class) + public void searchWithEmptyVector() { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = new ArrayList<>(); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr(" book_id > 1000 ") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); + Assert.assertTrue( + searchResultsR.getException().getMessage().contains("Target vectors can not be empty")); + } + + @Severity(SeverityLevel.MINOR) + @Test(description = "binary search with empty vector", expectedExceptions = ParamException.class) + public void binarySearchWithEmptyVector() { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List search_vectors = new ArrayList<>(); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(search_vectors) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .withExpr(" book_id > 1000 ") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); + Assert.assertTrue( + searchResultsR.getException().getMessage().contains("Target vectors can not be empty")); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "int PK and float vector search after insert the entity", + dataProvider = "providerPartition") + public void intPKAndFloatVectorSearchAfterInsertNewEntity(Boolean usePart) + throws InterruptedException { + // insert entity first + List book_id_array = + new ArrayList() { + { + add(9999L); + } + }; + List word_count_array = + new ArrayList() { + { + add(19999L); + } + }; + List fs = Arrays.asList(MathUtil.generateFloat(128)); + List> book_intro_array = + new ArrayList>() { + { + add(fs); + } + }; + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_id", book_id_array)); + fields.add(new InsertParam.Field("word_count", word_count_array)); + fields.add( + new InsertParam.Field( + CommonData.defaultVectorField, book_intro_array)); + milvusClient.insert( + InsertParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withPartitionName(usePart ? CommonData.defaultPartition : "") + .withFields(fields) + .build()); + Thread.sleep(2000); + // search + Integer SEARCH_K = 1; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id", "word_count"); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultPartition) : Arrays.asList()) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(book_intro_array) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr("book_id == 9999") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("word_count", 0).get(0), 19999L); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).get(0), 9999L); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "int PK and binary vector search after insert the entity", + dataProvider = "providerPartition") + public void intPKAndBinaryVectorSearchAfterInsertNewEntity(Boolean usePart) + throws InterruptedException { + // insert entity first + List book_id_array = + new ArrayList() { + { + add(9999L); + } + }; + List word_count_array = + new ArrayList() { + { + add(19999L); + } + }; + List book_intro_array = CommonFunction.generateBinaryVectors(1, 128); + + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_id", book_id_array)); + fields.add(new InsertParam.Field("word_count", word_count_array)); + fields.add( + new InsertParam.Field( + CommonData.defaultBinaryVectorField, book_intro_array)); + milvusClient.insert( + InsertParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .withPartitionName(usePart ? CommonData.defaultBinaryPartition : "") + .withFields(fields) + .build()); + Thread.sleep(2000); + // search + Integer SEARCH_K = 1; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id", "word_count"); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultBinaryPartition) : Arrays.asList()) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(book_intro_array) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("word_count", 0).get(0), 19999L); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).get(0), 9999L); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "string PK and float vector search after insert the entity", + dataProvider = "providerPartition") + public void stringPKAndFloatVectorSearchAfterInsertNewEntity(Boolean usePart) + throws InterruptedException { + // insert entity first + newBookName = MathUtil.genRandomStringAndChinese(10); + String newBookContent = MathUtil.genRandomStringAndChinese(20); + System.out.println("newBookContent:" + newBookContent); + List book_name_array = + new ArrayList() { + { + add(newBookName); + } + }; + List book_content_array = + new ArrayList() { + { + add(newBookContent); + } + }; + List fs = Arrays.asList(MathUtil.generateFloat(128)); + List> book_intro_array = + new ArrayList>() { + { + add(fs); + } + }; + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_name", book_name_array)); + fields.add(new InsertParam.Field("book_content", book_content_array)); + fields.add( + new InsertParam.Field( + CommonData.defaultVectorField, book_intro_array)); + milvusClient.insert( + InsertParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withPartitionName(usePart ? CommonData.defaultStringPKPartition : "") + .withFields(fields) + .build()); + Thread.sleep(2000); + // search + Integer SEARCH_K = 1; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name", "book_content"); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultStringPKPartition) : Arrays.asList()) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(book_intro_array) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr("book_name == \"" + newBookName + "\"") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals( + searchResultsWrapper.getFieldData("book_content", 0).get(0), newBookContent); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).get(0), newBookName); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "string PK and binary vector search after insert the entity", + dataProvider = "providerPartition") + public void stringPKAndBinaryVectorSearchAfterInsertNewEntity(Boolean usePart) + throws InterruptedException { + // insert entity first + newBookNameBin = MathUtil.genRandomStringAndChinese(10); + String newBookContent = MathUtil.genRandomStringAndChinese(20); + List book_name_array = + new ArrayList() { + { + add(newBookNameBin); + } + }; + List book_content_array = + new ArrayList() { + { + add(newBookContent); + } + }; + List book_intro_array = CommonFunction.generateBinaryVectors(1, 128); + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_name", book_name_array)); + fields.add(new InsertParam.Field("book_content", book_content_array)); + fields.add( + new InsertParam.Field( + CommonData.defaultBinaryVectorField, book_intro_array)); + milvusClient.insert( + InsertParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKBinaryCollection) + .withPartitionName(usePart ? CommonData.defaultStringPKBinaryPartition : "") + .withFields(fields) + .build()); + Thread.sleep(2000); + // search + Integer SEARCH_K = 1; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name", "book_content"); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKBinaryCollection) + .withPartitionNames( + usePart + ? Arrays.asList(CommonData.defaultStringPKBinaryPartition) + : Arrays.asList()) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withVectors(book_intro_array) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .withExpr("book_name == \"" + newBookNameBin + "\"") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals( + searchResultsWrapper.getFieldData("book_content", 0).get(0), newBookContent); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).get(0), newBookNameBin); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "int PK and float vector search after update the entity", + dataProvider = "providerPartition") + public void intPKAndFloatVectorSearchAfterUpdateEntity(Boolean usePart) + throws InterruptedException { + Random random = new Random(); + int id = random.nextInt(2000); + // update entity first + List book_id_array = + new ArrayList() { + { + add((long) id); + } + }; + List word_count_array = + new ArrayList() { + { + add(19999L); + } + }; + List fs = Arrays.asList(MathUtil.generateFloat(128)); + List> book_intro_array = + new ArrayList>() { + { + add(fs); + } + }; + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_id", book_id_array)); + fields.add(new InsertParam.Field("word_count", word_count_array)); + fields.add( + new InsertParam.Field( + CommonData.defaultVectorField, book_intro_array)); + milvusClient.insert( + InsertParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withPartitionName(usePart ? CommonData.defaultPartition : "") + .withFields(fields) + .build()); + Thread.sleep(2000); + // search + Integer SEARCH_K = 1; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id", "word_count"); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultPartition) : Arrays.asList()) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withVectors(book_intro_array) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr("book_id == " + id) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("word_count", 0).get(0), 19999L); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "int PK and binary vector search after update the entity", + dataProvider = "providerPartition") + public void intPKAndBinaryVectorSearchAfterUpdateEntity(Boolean usePart) + throws InterruptedException { + Random random = new Random(); + int id = random.nextInt(2000); + // update entity first + List book_id_array = + new ArrayList() { + { + add((long) id); + } + }; + List word_count_array = + new ArrayList() { + { + add(19999L); + } + }; + List book_intro_array = CommonFunction.generateBinaryVectors(1, 128); + + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_id", book_id_array)); + fields.add(new InsertParam.Field("word_count", word_count_array)); + fields.add( + new InsertParam.Field( + CommonData.defaultBinaryVectorField, book_intro_array)); + milvusClient.insert( + InsertParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .withPartitionName(usePart ? CommonData.defaultBinaryPartition : "") + .withFields(fields) + .build()); + Thread.sleep(2000); + // search + Integer SEARCH_K = 1; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id", "word_count"); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultBinaryPartition) : Arrays.asList()) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withVectors(book_intro_array) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("word_count", 0).get(0), 19999L); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "string PK and float vector search after update the entity", + dataProvider = "providerPartition", + dependsOnMethods = "stringPKAndFloatVectorSearchAfterInsertNewEntity") + public void stringPKAndFloatVectorSearchAfterUpdateNewEntity(Boolean usePart) + throws InterruptedException { + // delete entity first + milvusClient.delete( + DeleteParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withPartitionName(usePart ? CommonData.defaultStringPKPartition : "") + .withExpr("book_name in [\"" + newBookName + "\"]") + .build()); + Thread.sleep(4000); + // update entity first + String newBookContent = MathUtil.genRandomStringAndChinese(20); + System.out.println("newBookContent:" + newBookContent); + List book_name_array = + new ArrayList() { + { + add(newBookName); + } + }; + List book_content_array = + new ArrayList() { + { + add(newBookContent); + } + }; + List fs = Arrays.asList(MathUtil.generateFloat(128)); + List> book_intro_array = + new ArrayList>() { + { + add(fs); + } + }; + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_name", book_name_array)); + fields.add(new InsertParam.Field("book_content", book_content_array)); + fields.add( + new InsertParam.Field( + CommonData.defaultVectorField, book_intro_array)); + milvusClient.insert( + InsertParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withPartitionName(usePart ? CommonData.defaultStringPKPartition : "") + .withFields(fields) + .build()); + Thread.sleep(2000); + // search + Integer SEARCH_K = 1; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name", "book_content"); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultStringPKPartition) : Arrays.asList()) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withVectors(book_intro_array) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .withExpr("book_name == \"" + newBookName + "\"") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals( + searchResultsWrapper.getFieldData("book_content", 0).get(0), newBookContent); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).get(0), newBookName); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "string PK and float vector search after update the entity", + dataProvider = "providerPartition", + dependsOnMethods = "stringPKAndBinaryVectorSearchAfterInsertNewEntity") + public void stringPKAndBinaryVectorSearchAfterUpdateNewEntity(Boolean usePart) + throws InterruptedException { + // delete entity first milvusClient.delete( - DeleteParam.newBuilder() + DeleteParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKBinaryCollection) + .withPartitionName(usePart ? CommonData.defaultStringPKBinaryPartition : "") + .withExpr("book_name in [\"" + newBookNameBin + "\"]") + .build()); + Thread.sleep(2000); + // insert entity first + String newBookContent = MathUtil.genRandomStringAndChinese(20); + List book_name_array = + new ArrayList() { + { + add(newBookNameBin); + } + }; + List book_content_array = + new ArrayList() { + { + add(newBookContent); + } + }; + List book_intro_array = CommonFunction.generateBinaryVectors(1, 128); + List fields = new ArrayList<>(); + fields.add(new InsertParam.Field("book_name", book_name_array)); + fields.add(new InsertParam.Field("book_content", book_content_array)); + fields.add( + new InsertParam.Field( + CommonData.defaultBinaryVectorField, book_intro_array)); + milvusClient.insert( + InsertParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKBinaryCollection) + .withPartitionName(usePart ? CommonData.defaultStringPKBinaryPartition : "") + .withFields(fields) + .build()); + Thread.sleep(2000); + // search + Integer SEARCH_K = 1; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name", "book_content"); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKBinaryCollection) + .withPartitionNames( + usePart + ? Arrays.asList(CommonData.defaultStringPKBinaryPartition) + : Arrays.asList()) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withVectors(book_intro_array) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .withExpr("book_name == \"" + newBookNameBin + "\"") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals( + searchResultsWrapper.getFieldData("book_content", 0).get(0), newBookContent); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).get(0), newBookNameBin); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "int PK and float vector search after delete data", + dataProvider = "providerPartition") + public void intPKAndFloatVectorSearchAfterDelete(Boolean usePart) throws InterruptedException { + R mutationResultR = + milvusClient.delete( + DeleteParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withPartitionName(usePart ? CommonData.defaultPartition : "") + .withExpr("book_id in [1,2,3]") + .build()); + Assert.assertEquals(mutationResultR.getData().getDeleteCnt(), 3L); + Thread.sleep(2000); + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultPartition) : Arrays.asList()) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr(" book_id in [1,2,3] ") + .build(); + R searchResultsR = milvusClient.search(searchParam); + System.out.println(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + Assert.assertEquals(searchResultsR.getData().getResults().getFieldsDataCount(), 0); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "int PK and binary vector search after delete data", + dataProvider = "providerPartition") + public void intPKAndBinaryVectorSearchAfterDelete(Boolean usePart) throws InterruptedException { + R mutationResultR = + milvusClient.delete( + DeleteParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .withPartitionName(usePart ? CommonData.defaultBinaryPartition : "") + .withExpr("book_id in [1,2,3]") + .build()); + Assert.assertEquals(mutationResultR.getData().getDeleteCnt(), 3L); + Thread.sleep(2000); + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List search_vectors = CommonFunction.generateBinaryVectors(1, 128); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultBinaryPartition) : Arrays.asList()) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(search_vectors) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .withExpr(" book_id in [1,2,3] ") + .build(); + R searchResultsR = milvusClient.search(searchParam); + System.out.println(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + Assert.assertEquals(searchResultsR.getData().getResults().getFieldsDataCount(), 0); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "string PK and float vector search after delete the entity", + dataProvider = "providerPartition", + dependsOnMethods = { + "stringPKAndFloatVectorSearchAfterInsertNewEntity", + "stringPKAndFloatVectorSearchAfterUpdateNewEntity" + }) + public void stringPKAndFloatVectorSearchAfterDelete(Boolean usePart) throws InterruptedException { + // delete entity first + milvusClient.delete( + DeleteParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withPartitionName(usePart ? CommonData.defaultStringPKPartition : "") + .withExpr("book_name in [\"" + newBookName + "\"]") + .build()); + Thread.sleep(2000); + + List fs = Arrays.asList(MathUtil.generateFloat(128)); + List> book_intro_array = + new ArrayList>() { + { + add(fs); + } + }; + + Thread.sleep(2000); + // search + Integer SEARCH_K = 1; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name", "book_content"); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withPartitionNames( + usePart ? Arrays.asList(CommonData.defaultStringPKPartition) : Arrays.asList()) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(book_intro_array) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr("book_name in [\"" + newBookName + "\"]") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + Assert.assertEquals(searchResultsR.getData().getStatus().getReason(), "search result is empty"); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.NORMAL) + @Test( + description = "string PK and Binary vector search after delete the entity", + dataProvider = "providerPartition", + dependsOnMethods = { + "stringPKAndBinaryVectorSearchAfterInsertNewEntity", + "stringPKAndBinaryVectorSearchAfterUpdateNewEntity" + }) + public void stringPKAndBinaryVectorSearchAfterDelete(Boolean usePart) + throws InterruptedException { + // delete entity first + milvusClient.delete( + DeleteParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKBinaryCollection) + .withPartitionName(usePart ? CommonData.defaultStringPKBinaryPartition : "") + .withExpr("book_name in [\"" + newBookNameBin + "\"]") + .build()); + Thread.sleep(2000); + List book_intro_array = CommonFunction.generateBinaryVectors(1, 128); + // search + Integer SEARCH_K = 1; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name", "book_content"); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKBinaryCollection) + .withPartitionNames( + usePart + ? Arrays.asList(CommonData.defaultStringPKBinaryPartition) + : Arrays.asList()) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(book_intro_array) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .withExpr("book_name in [\"" + newBookNameBin + "\"]") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + Assert.assertEquals(searchResultsR.getData().getStatus().getReason(), "search result is empty"); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.CRITICAL) + @Test(description = "int PK and float vector search by alias") + public void intPKAndFloatVectorSearchByAlias() { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultAlias) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsR.getData().getResults().getTopK(), 2); + Assert.assertEquals( + searchResultsR.getData().getResults().getIds().getIntId().getDataCount(), 2); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.MINOR) + @Test(description = "int PK and float vector search by alias") + public void intPKAndFloatVectorSearchByNonexistentAlias() { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName("NonexistentAlias") + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); + Assert.assertEquals( + searchResultsR.getException().getMessage(), + "DescribeCollection failed: can't find collection: NonexistentAlias"); + } + + @Severity(SeverityLevel.CRITICAL) + @Test(description = "int pk and binary vector search by alias") + public void intPKAndBinaryVectorSearchByAlias() { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List search_vectors = CommonFunction.generateBinaryVectors(1, 128); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultBinaryAlias) + .withMetricType(MetricType.JACCARD) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(search_vectors) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + System.out.println(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsR.getData().getResults().getTopK(), 2); + Assert.assertEquals( + searchResultsR.getData().getResults().getIds().getIntId().getDataCount(), 2); + } + + @Severity(SeverityLevel.CRITICAL) + @Test(description = "search with each consistency level", dataProvider = "providerConsistency") + public void intPKSearchWithConsistencyLevel(ConsistencyLevelEnum consistencyLevel) { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withConsistencyLevel(consistencyLevel) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).size(), 2); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.CRITICAL) + @Test( + description = "String Pk and float vector search with consistency", + dataProvider = "providerConsistency") + public void stringPKSearchWithConsistencyLevel(ConsistencyLevelEnum consistencyLevel) { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withConsistencyLevel(consistencyLevel) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).size(), 2); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.CRITICAL) + @Test(description = "Int PK and float vector search with each index", dataProvider = "FloatIndex") + public void intPKAndFloatVectorSearchWithEachIndex(IndexType indexType, MetricType metricType) { + String newCollection = CommonFunction.createNewCollection(); + // create index + R rpcStatusR = + milvusClient.createIndex( + CreateIndexParam.newBuilder() + .withCollectionName(newCollection) + .withFieldName(CommonData.defaultVectorField) + .withIndexName(CommonData.defaultIndex) + .withMetricType(metricType) + .withIndexType(indexType) + .withExtraParam(CommonFunction.provideExtraParam(indexType)) + .withSyncMode(Boolean.FALSE) + .build()); + System.out.println("Create index" + rpcStatusR); + Assert.assertEquals(rpcStatusR.getStatus().intValue(), 0); + Assert.assertEquals(rpcStatusR.getData().getMsg(), "Success"); + // Insert test data + List fields = CommonFunction.generateData(1000); + milvusClient.insert( + InsertParam.newBuilder().withCollectionName(newCollection).withFields(fields).build()); + // load + milvusClient.loadCollection( + LoadCollectionParam.newBuilder() + .withCollectionName(newCollection) + .withSyncLoad(true) + .withSyncLoadWaitingInterval(500L) + .withSyncLoadWaitingTimeout(30L) + .build()); + // search + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(newCollection) + .withMetricType(metricType) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).size(), 2); + System.out.println(searchResultsR.getData().getResults()); + // drop collection + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(newCollection).build()); + } + + @Severity(SeverityLevel.CRITICAL) + @Test( + description = "String PK and Binary vector search with each index", + dataProvider = "BinaryIndex") + public void stringPKAndBinaryVectorSearchWithEachIndex( + IndexType indexType, MetricType metricType) { + String stringPKAndBinaryCollection = CommonFunction.createStringPKAndBinaryCollection(); + // create index + R rpcStatusR = + milvusClient.createIndex( + CreateIndexParam.newBuilder() + .withCollectionName(stringPKAndBinaryCollection) + .withFieldName(CommonData.defaultBinaryVectorField) + .withIndexName(CommonData.defaultBinaryIndex) + .withMetricType(metricType) + .withIndexType(indexType) + .withExtraParam(CommonData.defaultExtraParam) + .withSyncMode(Boolean.FALSE) + .build()); + System.out.println("Create index" + rpcStatusR); + Assert.assertEquals(rpcStatusR.getStatus().intValue(), 0); + Assert.assertEquals(rpcStatusR.getData().getMsg(), "Success"); + // Insert test data + List fields = CommonFunction.generateStringPKBinaryData(2000); + milvusClient.insert( + InsertParam.newBuilder() + .withFields(fields) + .withCollectionName(stringPKAndBinaryCollection) + .build()); + // load + milvusClient.loadCollection( + LoadCollectionParam.newBuilder() + .withCollectionName(stringPKAndBinaryCollection) + .withSyncLoad(true) + .withSyncLoadWaitingInterval(500L) + .withSyncLoadWaitingTimeout(30L) + .build()); + // search + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name"); + List search_vectors = CommonFunction.generateBinaryVectors(1, 128); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(stringPKAndBinaryCollection) + .withMetricType(metricType) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withBinaryVectors(search_vectors) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + System.out.println(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).size(), 2); + // drop collection + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(stringPKAndBinaryCollection).build()); + } + + @Severity(SeverityLevel.CRITICAL) + @Test(description = "Int PK search with each expression", dataProvider = "provideIntExpressions") + public void intPKSearchWithEachExpressions(String express) { + Integer SEARCH_K = 4; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr(express) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertTrue(searchResultsWrapper.getFieldData("book_id", 0).size() >= 1); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.CRITICAL) + @Test( + description = "string PK Search with each expressions", + dataProvider = "provideStringExpressions") + public void stringPKSearchWithEachExpressions(String expression) { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr(expression) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertTrue(searchResultsWrapper.getFieldData("book_name", 0).size() >= 1); + System.out.println(searchResultsR.getData().getResults()); + } + + @Severity(SeverityLevel.NORMAL) + @Test(description = "Search without load") + public void searchWithoutLoad() { + milvusClient.releaseCollection(ReleaseCollectionParam.newBuilder() .withCollectionName(CommonData.defaultCollection) - .withPartitionName(usePart ? CommonData.defaultPartition : "") - .withExpr("book_id in [1,2,3]") .build()); - Assert.assertEquals(mutationResultR.getData().getDeleteCnt(), 3L); - Thread.sleep(2000); - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultPartition) : Arrays.asList()) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr(" book_id in [1,2,3] ") - .build(); - R searchResultsR = milvusClient.search(searchParam); - System.out.println(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - Assert.assertEquals(searchResultsR.getData().getResults().getFieldsDataCount(), 0); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "int PK and binary vector search after delete data", - dataProvider = "providerPartition") - public void intPKAndBinaryVectorSearchAfterDelete(Boolean usePart) throws InterruptedException { - R mutationResultR = - milvusClient.delete( - DeleteParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .withPartitionName(usePart ? CommonData.defaultBinaryPartition : "") - .withExpr("book_id in [1,2,3]") + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); + Assert.assertTrue(searchResultsR.getException().getMessage().contains("not loaded into memory")); + milvusClient.loadCollection(LoadCollectionParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) .build()); - Assert.assertEquals(mutationResultR.getData().getDeleteCnt(), 3L); - Thread.sleep(2000); - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List search_vectors = CommonFunction.generateBinaryVectors(1, 128); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultBinaryPartition) : Arrays.asList()) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .withExpr(" book_id in [1,2,3] ") - .build(); - R searchResultsR = milvusClient.search(searchParam); - System.out.println(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - Assert.assertEquals(searchResultsR.getData().getResults().getFieldsDataCount(), 0); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "string PK and float vector search after delete the entity", - dataProvider = "providerPartition", - dependsOnMethods = { - "stringPKAndFloatVectorSearchAfterInsertNewEntity", - "stringPKAndFloatVectorSearchAfterUpdateNewEntity" - }) - public void stringPKAndFloatVectorSearchAfterDelete(Boolean usePart) throws InterruptedException { - // delete entity first - milvusClient.delete( - DeleteParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withPartitionName(usePart ? CommonData.defaultStringPKPartition : "") - .withExpr("book_name in [\"" + newBookName + "\"]") - .build()); - Thread.sleep(2000); - - List fs = Arrays.asList(MathUtil.generateFloat(128)); - List> book_intro_array = - new ArrayList>() { - { - add(fs); - } - }; - - Thread.sleep(2000); - // search - Integer SEARCH_K = 1; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name", "book_content"); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withPartitionNames( - usePart ? Arrays.asList(CommonData.defaultStringPKPartition) : Arrays.asList()) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(book_intro_array) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr("book_name in [\"" + newBookName + "\"]") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - Assert.assertEquals(searchResultsR.getData().getStatus().getReason(), "search result is empty"); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.NORMAL) - @Test( - description = "string PK and Binary vector search after delete the entity", - dataProvider = "providerPartition", - dependsOnMethods = { - "stringPKAndBinaryVectorSearchAfterInsertNewEntity", - "stringPKAndBinaryVectorSearchAfterUpdateNewEntity" - }) - public void stringPKAndBinaryVectorSearchAfterDelete(Boolean usePart) - throws InterruptedException { - // delete entity first - milvusClient.delete( - DeleteParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKBinaryCollection) - .withPartitionName(usePart ? CommonData.defaultStringPKBinaryPartition : "") - .withExpr("book_name in [\"" + newBookNameBin + "\"]") - .build()); - Thread.sleep(2000); - List book_intro_array = CommonFunction.generateBinaryVectors(1, 128); - // search - Integer SEARCH_K = 1; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name", "book_content"); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKBinaryCollection) - .withPartitionNames( - usePart - ? Arrays.asList(CommonData.defaultStringPKBinaryPartition) - : Arrays.asList()) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(book_intro_array) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .withExpr("book_name in [\"" + newBookNameBin + "\"]") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - Assert.assertEquals(searchResultsR.getData().getStatus().getReason(), "search result is empty"); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.CRITICAL) - @Test(description = "int PK and float vector search by alias") - public void intPKAndFloatVectorSearchByAlias() { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultAlias) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsR.getData().getResults().getTopK(), 2); - Assert.assertEquals( - searchResultsR.getData().getResults().getIds().getIntId().getDataCount(), 2); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.MINOR) - @Test(description = "int PK and float vector search by alias") - public void intPKAndFloatVectorSearchByNonexistentAlias() { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName("NonexistentAlias") - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); - Assert.assertEquals( - searchResultsR.getException().getMessage(), - "DescribeCollection failed: can't find collection: NonexistentAlias"); - } - - @Severity(SeverityLevel.CRITICAL) - @Test(description = "int pk and binary vector search by alias") - public void intPKAndBinaryVectorSearchByAlias() { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List search_vectors = CommonFunction.generateBinaryVectors(1, 128); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultBinaryAlias) - .withMetricType(MetricType.JACCARD) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - System.out.println(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsR.getData().getResults().getTopK(), 2); - Assert.assertEquals( - searchResultsR.getData().getResults().getIds().getIntId().getDataCount(), 2); - } - - @Severity(SeverityLevel.CRITICAL) - @Test(description = "search with each consistency level", dataProvider = "providerConsistency") - public void intPKSearchWithConsistencyLevel(ConsistencyLevelEnum consistencyLevel) { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withConsistencyLevel(consistencyLevel) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).size(), 2); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.CRITICAL) - @Test( - description = "String Pk and float vector search with consistency", - dataProvider = "providerConsistency") - public void stringPKSearchWithConsistencyLevel(ConsistencyLevelEnum consistencyLevel) { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withConsistencyLevel(consistencyLevel) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).size(), 2); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.CRITICAL) - @Test(description = "Int PK and float vector search with each index", dataProvider = "FloatIndex") - public void intPKAndFloatVectorSearchWithEachIndex(IndexType indexType, MetricType metricType) { - String newCollection = CommonFunction.createNewCollection(); - // create index - R rpcStatusR = - milvusClient.createIndex( - CreateIndexParam.newBuilder() - .withCollectionName(newCollection) - .withFieldName(CommonData.defaultVectorField) - .withIndexName(CommonData.defaultIndex) - .withMetricType(metricType) - .withIndexType(indexType) - .withExtraParam(CommonFunction.provideExtraParam(indexType)) - .withSyncMode(Boolean.FALSE) + } + + @Severity(SeverityLevel.NORMAL) + @Test(description = "string PK Search with error expressions") + public void stringPKSearchWithErrorExpressions() { + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_name"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultStringPKCollection) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withExpr(" book_name = a") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); + Assert.assertTrue(searchResultsR.getException().getMessage().contains("cannot parse expression")); + + } + + public long data1 = 0L; + public long data2 = 0L; + + @Severity(SeverityLevel.BLOCKER) + @Test( + description = + "Search with pagination(offset=0)", groups = {"Smoke"}) + public void intPKAndFloatVectorSearchWithPagination() { + Integer SEARCH_K = 4; // TopK + String SEARCH_PARAM = "{\"nprobe\":10,\"offset\":0}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).size(), 4); + data1 = searchResultsR.getData().getResults().getIds().getIntId().getData(2); + data2 = searchResultsR.getData().getResults().getIds().getIntId().getData(3); + } + + + @Severity(SeverityLevel.BLOCKER) + @Test( + description = + "Search with pagination.", + groups = {"Smoke"}, dependsOnMethods = "intPKAndFloatVectorSearchWithPagination") + public void intPKAndFloatVectorSearchWithPagination2() { + Integer SEARCH_K = 4; // TopK + String SEARCH_PARAM = "{\"nprobe\":10,\"offset\":2}"; + List search_output_fields = Arrays.asList("book_id"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(CommonData.defaultCollection) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).size(), 4); + Assert.assertEquals(searchResultsR.getData().getResults().getIds().getIntId().getData(0), data1); + Assert.assertEquals(searchResultsR.getData().getResults().getIds().getIntId().getData(1), data2); + logger.info(searchResultsR.getData().getResults().toString()); + } + + @Severity(SeverityLevel.BLOCKER) + @Test(description = "Search with DynamicField.", groups = {"Smoke"}, dataProvider = "dynamicExpressions") + public void searchWithDynamicField(String expr) { + List jsonObjects = CommonFunction.generateDataWithDynamicFiledRow(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withRows(jsonObjects) + .withCollectionName(collectionWithDynamicField) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + CommonFunction.createIndexWithLoad(collectionWithDynamicField, IndexType.HNSW, MetricType.L2, CommonData.defaultVectorField); + // search + Integer SEARCH_K = 10; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("extra_field"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithDynamicField) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) + .withExpr(expr) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertTrue(searchResultsWrapper.getFieldData("$meta", 0).size() >= 4); + logger.info(searchResultsR.getData().getResults().toString()); + System.out.println(searchResultsWrapper.getFieldData("$meta", 0).size()); + } + + @Severity(SeverityLevel.NORMAL) + @Test(description = "Search with DynamicField use nonexistent field name") + public void searchWithDynamicFieldUseNonexistentFiledName() { + List jsonObjects = CommonFunction.generateDataWithDynamicFiledRow(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withRows(jsonObjects) + .withCollectionName(collectionWithDynamicField) .build()); - System.out.println("Create index" + rpcStatusR); - Assert.assertEquals(rpcStatusR.getStatus().intValue(), 0); - Assert.assertEquals(rpcStatusR.getData().getMsg(), "Success"); - // Insert test data - List fields = CommonFunction.generateData(1000); - milvusClient.insert( - InsertParam.newBuilder().withCollectionName(newCollection).withFields(fields).build()); - // load - milvusClient.loadCollection( - LoadCollectionParam.newBuilder() - .withCollectionName(newCollection) - .withSyncLoad(true) - .withSyncLoadWaitingInterval(500L) - .withSyncLoadWaitingTimeout(30L) - .build()); - // search - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(newCollection) - .withMetricType(metricType) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).size(), 2); - System.out.println(searchResultsR.getData().getResults()); - // drop collection - milvusClient.dropCollection( - DropCollectionParam.newBuilder().withCollectionName(newCollection).build()); - } - - @Severity(SeverityLevel.CRITICAL) - @Test( - description = "String PK and Binary vector search with each index", - dataProvider = "BinaryIndex") - public void stringPKAndBinaryVectorSearchWithEachIndex( - IndexType indexType, MetricType metricType) { - String stringPKAndBinaryCollection = CommonFunction.createStringPKAndBinaryCollection(); - // create index - R rpcStatusR = - milvusClient.createIndex( - CreateIndexParam.newBuilder() - .withCollectionName(stringPKAndBinaryCollection) - .withFieldName(CommonData.defaultBinaryVectorField) - .withIndexName(CommonData.defaultBinaryIndex) - .withMetricType(metricType) - .withIndexType(indexType) - .withExtraParam(CommonData.defaultExtraParam) - .withSyncMode(Boolean.FALSE) + Assert.assertEquals(insert.getStatus().intValue(), 0); + CommonFunction.createIndexWithLoad(collectionWithDynamicField, IndexType.HNSW, MetricType.L2, CommonData.defaultVectorField); + // search + Integer SEARCH_K = 10; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("extra_field_nonexistent"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithDynamicField) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) + .withExpr(" extra_field2 > 100 ") + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("$meta", 0).size(), 10); + logger.info(searchResultsR.getData().getResults().toString()); + + } + + @Severity(SeverityLevel.BLOCKER) + @Test(description = "Search with JSON field.", groups = {"Smoke"}, dataProvider = "jsonExpressions") + public void searchWithJsonField(String expr,int topK,int expected) { + List jsonObjects = CommonFunction.generateJsonData(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withRows(jsonObjects) + .withCollectionName(collectionWithJsonField) .build()); - System.out.println("Create index" + rpcStatusR); - Assert.assertEquals(rpcStatusR.getStatus().intValue(), 0); - Assert.assertEquals(rpcStatusR.getData().getMsg(), "Success"); - // Insert test data - List fields = CommonFunction.generateStringPKBinaryData(2000); - milvusClient.insert( - InsertParam.newBuilder() - .withFields(fields) - .withCollectionName(stringPKAndBinaryCollection) - .build()); - // load - milvusClient.loadCollection( - LoadCollectionParam.newBuilder() - .withCollectionName(stringPKAndBinaryCollection) - .withSyncLoad(true) - .withSyncLoadWaitingInterval(500L) - .withSyncLoadWaitingTimeout(30L) - .build()); - // search - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name"); - List search_vectors = CommonFunction.generateBinaryVectors(1, 128); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(stringPKAndBinaryCollection) - .withMetricType(metricType) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultBinaryVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - System.out.println(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_name", 0).size(), 2); - // drop collection - milvusClient.dropCollection( - DropCollectionParam.newBuilder().withCollectionName(stringPKAndBinaryCollection).build()); - } - - @Severity(SeverityLevel.CRITICAL) - @Test(description = "Int PK search with each expression", dataProvider = "provideIntExpressions") - public void intPKSearchWithEachExpressions(String express) { - Integer SEARCH_K = 4; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr(express) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertTrue(searchResultsWrapper.getFieldData("book_id",0).size() >= 1); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.CRITICAL) - @Test( - description = "string PK Search with each expressions", - dataProvider = "provideStringExpressions") - public void stringPKSearchWithEachExpressions(String expression) { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr(expression) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertTrue(searchResultsWrapper.getFieldData("book_name", 0).size()>=1); - System.out.println(searchResultsR.getData().getResults()); - } - - @Severity(SeverityLevel.NORMAL) - @Test(description = "Search without load") - public void searchWithoutLoad(){ - milvusClient.releaseCollection(ReleaseCollectionParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .build()); - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(),1); - Assert.assertTrue(searchResultsR.getException().getMessage().contains("not loaded into memory")); - milvusClient.loadCollection(LoadCollectionParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .build()); - } - - @Severity(SeverityLevel.NORMAL) - @Test(description = "string PK Search with error expressions") - public void stringPKSearchWithErrorExpressions() { - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_name"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultStringPKCollection) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withExpr( " book_name = a") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 1); - Assert.assertTrue(searchResultsR.getException().getMessage().contains("cannot parse expression")); - - } - - public long data1=0L; - public long data2=0L; - - @Severity(SeverityLevel.BLOCKER) - @Test( - description = - "Search with pagination(offset=0)",groups = {"Smoke"}) - public void intPKAndFloatVectorSearchWithPagination() { - Integer SEARCH_K = 4; // TopK - String SEARCH_PARAM = "{\"nprobe\":10,\"offset\":0}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).size(), 4); - data1=searchResultsR.getData().getResults().getIds().getIntId().getData(2); - data2=searchResultsR.getData().getResults().getIds().getIntId().getData(3); - } - - - @Severity(SeverityLevel.BLOCKER) - @Test( - description = - "Search with pagination.", - groups = {"Smoke"},dependsOnMethods = "intPKAndFloatVectorSearchWithPagination") - public void intPKAndFloatVectorSearchWithPagination2() { - Integer SEARCH_K = 4; // TopK - String SEARCH_PARAM = "{\"nprobe\":10,\"offset\":2}"; - List search_output_fields = Arrays.asList("book_id"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(CommonData.defaultCollection) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("book_id", 0).size(), 4); - Assert.assertEquals(searchResultsR.getData().getResults().getIds().getIntId().getData(0),data1); - Assert.assertEquals(searchResultsR.getData().getResults().getIds().getIntId().getData(1),data2); - logger.info(searchResultsR.getData().getResults().toString()); - } - - @Severity(SeverityLevel.BLOCKER) - @Test(description = "Search with DynamicField.", groups = {"Smoke"},dataProvider = "dynamicExpressions") - public void searchWithDynamicField(String expr){ - List jsonObjects = CommonFunction.generateDataWithDynamicFiledRow(1000); - R insert = milvusClient.insert(InsertParam.newBuilder() - .withRows(jsonObjects) - .withCollectionName(collectionWithDynamicField) - .build()); - Assert.assertEquals(insert.getStatus().intValue(),0); - CommonFunction.createIndexWithLoad(collectionWithDynamicField,IndexType.HNSW,MetricType.L2,CommonData.defaultVectorField); - // search - Integer SEARCH_K = 10; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("extra_field"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(collectionWithDynamicField) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) - .withExpr(expr) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertTrue(searchResultsWrapper.getFieldData("$meta", 0).size()>=4); - logger.info(searchResultsR.getData().getResults().toString()); - System.out.println(searchResultsWrapper.getFieldData("$meta", 0).size()); - } - - @Severity(SeverityLevel.NORMAL) - @Test(description = "Search with DynamicField use nonexistent field name") - public void searchWithDynamicFieldUseNonexistentFiledName(){ - List jsonObjects = CommonFunction.generateDataWithDynamicFiledRow(1000); - R insert = milvusClient.insert(InsertParam.newBuilder() - .withRows(jsonObjects) - .withCollectionName(collectionWithDynamicField) - .build()); - Assert.assertEquals(insert.getStatus().intValue(),0); - CommonFunction.createIndexWithLoad(collectionWithDynamicField,IndexType.HNSW,MetricType.L2,CommonData.defaultVectorField); - // search - Integer SEARCH_K = 10; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("extra_field_nonexistent"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(collectionWithDynamicField) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED) - .withExpr(" extra_field2 > 100 ") - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData("$meta", 0).size(), 10); - logger.info(searchResultsR.getData().getResults().toString()); - - } - - @Severity(SeverityLevel.BLOCKER) - @Test(description = "Search with JSON field.", groups = {"Smoke"},dataProvider = "jsonExpressions") - public void searchWithJsonField(String expr) { - List jsonObjects = CommonFunction.generateJsonData(1000); - R insert = milvusClient.insert(InsertParam.newBuilder() - .withRows(jsonObjects) - .withCollectionName(collectionWithJsonField) - .build()); - Assert.assertEquals(insert.getStatus().intValue(), 0); - CommonFunction.createIndexWithLoad(collectionWithJsonField, IndexType.HNSW, MetricType.L2, "float_vector"); - // search - Integer SEARCH_K = 10; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("json_field"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(collectionWithJsonField) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName("float_vector") - .withParams(SEARCH_PARAM) - .withExpr(expr) - .withConsistencyLevel(ConsistencyLevelEnum.STRONG) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertTrue(searchResultsWrapper.getFieldData("json_field", 0).size()>=4); - // 按照列获取数据 - FieldDataWrapper json_field = searchResultsWrapper.getFieldWrapper("json_field"); - String string_field = json_field.getAsString(0, "string_field"); - Assert.assertTrue(string_field.contains("Str")); - // 按照行 - JSONObject jsonObject= (JSONObject) searchResultsWrapper.getIDScore(0).get(0).get("json_field"); - String string = jsonObject.getString("string_field"); - Assert.assertTrue(string.contains("Str")); - - - } - - @Severity(SeverityLevel.BLOCKER) - @Test(description = "Int PK and float vector search with each index", dataProvider = "FloatIndex") - public void searchReturnVector(IndexType indexType, MetricType metricType) { - String newCollection = CommonFunction.createNewCollection(); - // create index - R rpcStatusR = - milvusClient.createIndex( - CreateIndexParam.newBuilder() - .withCollectionName(newCollection) - .withFieldName(CommonData.defaultVectorField) - .withIndexName(CommonData.defaultIndex) - .withMetricType(metricType) - .withIndexType(indexType) - .withExtraParam(CommonFunction.provideExtraParam(indexType)) - .withSyncMode(Boolean.FALSE) - .build()); - System.out.println("Create index" + rpcStatusR); - Assert.assertEquals(rpcStatusR.getStatus().intValue(), 0); - Assert.assertEquals(rpcStatusR.getData().getMsg(), "Success"); - // Insert test data - List fields = CommonFunction.generateData(1000); - milvusClient.insert( - InsertParam.newBuilder().withCollectionName(newCollection).withFields(fields).build()); - // load - milvusClient.loadCollection( - LoadCollectionParam.newBuilder() - .withCollectionName(newCollection) - .withSyncLoad(true) - .withSyncLoadWaitingInterval(500L) - .withSyncLoadWaitingTimeout(30L) - .build()); - // search - Integer SEARCH_K = 2; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("book_id",CommonData.defaultVectorField); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(newCollection) - .withMetricType(metricType) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName(CommonData.defaultVectorField) - .withParams(SEARCH_PARAM) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertEquals(searchResultsWrapper.getFieldData(CommonData.defaultVectorField, 0).size(), 2); - System.out.println(searchResultsR.getData().getResults()); - // drop collection - milvusClient.dropCollection( - DropCollectionParam.newBuilder().withCollectionName(newCollection).build()); - } - - @Severity(SeverityLevel.BLOCKER) - @Test(description = "Search with array field",groups = {"Smoke"}) - public void searchWithArrayField(){ - List jsonObjects = CommonFunction.generateJsonDataWithArrayField(1000); - R insert = milvusClient.insert(InsertParam.newBuilder() - .withRows(jsonObjects) - .withCollectionName(collectionWithArrayField) - .build()); - Assert.assertEquals(insert.getStatus().intValue(), 0); - CommonFunction.createIndexWithLoad(collectionWithArrayField, IndexType.HNSW, MetricType.L2, "float_vector"); - // search - Integer SEARCH_K = 10; // TopK - String SEARCH_PARAM = "{\"nprobe\":10}"; - List search_output_fields = Arrays.asList("str_array_field","int_array_field","float_array_field"); - List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); - SearchParam searchParam = - SearchParam.newBuilder() - .withCollectionName(collectionWithArrayField) - .withMetricType(MetricType.L2) - .withOutFields(search_output_fields) - .withTopK(SEARCH_K) - .withVectors(search_vectors) - .withVectorFieldName("float_vector") - .withParams(SEARCH_PARAM) + Assert.assertEquals(insert.getStatus().intValue(), 0); + CommonFunction.createIndexWithLoad(collectionWithJsonField, IndexType.HNSW, MetricType.L2, "float_vector"); + // search + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("*"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithJsonField) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(topK) + .withFloatVectors(search_vectors) + .withVectorFieldName("float_vector") + .withParams(SEARCH_PARAM) + .withExpr(expr) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + Assert.assertEquals(searchResultsR.getData().getResults().getTopK(),expected); + /* // 按照列获取数据 + FieldDataWrapper json_field = searchResultsWrapper.getFieldWrapper("json_field"); + String string_field = json_field.getAsString(0, "string_field"); + Assert.assertTrue(string_field.contains("Str")); + // 按照行 + JSONObject jsonObject = (JSONObject) searchResultsWrapper.getIDScore(0).get(0).get("json_field"); + String string = jsonObject.getString("string_field"); + Assert.assertTrue(string.contains("Str"));*/ + + + } + + @Severity(SeverityLevel.BLOCKER) + @Test(description = "Int PK and float vector search with each index", dataProvider = "FloatIndex") + public void searchReturnVector(IndexType indexType, MetricType metricType) { + String newCollection = CommonFunction.createNewCollection(); + // create index + R rpcStatusR = + milvusClient.createIndex( + CreateIndexParam.newBuilder() + .withCollectionName(newCollection) + .withFieldName(CommonData.defaultVectorField) + .withIndexName(CommonData.defaultIndex) + .withMetricType(metricType) + .withIndexType(indexType) + .withExtraParam(CommonFunction.provideExtraParam(indexType)) + .withSyncMode(Boolean.FALSE) + .build()); + System.out.println("Create index" + rpcStatusR); + Assert.assertEquals(rpcStatusR.getStatus().intValue(), 0); + Assert.assertEquals(rpcStatusR.getData().getMsg(), "Success"); + // Insert test data + List fields = CommonFunction.generateData(1000); + milvusClient.insert( + InsertParam.newBuilder().withCollectionName(newCollection).withFields(fields).build()); + // load + milvusClient.loadCollection( + LoadCollectionParam.newBuilder() + .withCollectionName(newCollection) + .withSyncLoad(true) + .withSyncLoadWaitingInterval(500L) + .withSyncLoadWaitingTimeout(30L) + .build()); + // search + Integer SEARCH_K = 2; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("book_id", CommonData.defaultVectorField); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(newCollection) + .withMetricType(metricType) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultVectorField) + .withParams(SEARCH_PARAM) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData(CommonData.defaultVectorField, 0).size(), 2); + System.out.println(searchResultsR.getData().getResults()); + // drop collection + milvusClient.dropCollection( + DropCollectionParam.newBuilder().withCollectionName(newCollection).build()); + } + + @Severity(SeverityLevel.BLOCKER) + @Test(description = "Search with array field", groups = {"Smoke"}) + public void searchWithArrayField() { + List jsonObjects = CommonFunction.generateJsonDataWithArrayField(1000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withRows(jsonObjects) + .withCollectionName(collectionWithArrayField) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + CommonFunction.createIndexWithLoad(collectionWithArrayField, IndexType.HNSW, MetricType.L2, "float_vector"); + // search + Integer SEARCH_K = 10; // TopK + String SEARCH_PARAM = "{\"nprobe\":10}"; + List search_output_fields = Arrays.asList("str_array_field", "int_array_field", "float_array_field"); + List> search_vectors = Arrays.asList(Arrays.asList(MathUtil.generateFloat(128))); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithArrayField) + .withMetricType(MetricType.L2) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withFloatVectors(search_vectors) + .withVectorFieldName("float_vector") + .withParams(SEARCH_PARAM) +// .withExpr(expr) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertTrue(searchResultsWrapper.getFieldData("str_array_field", 0).size() >= 4); + } + + @Test(description = "Search with float16 vector", groups = {"Smoke"}) + public void searchWithFloat16Vector() { + + // search + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithFloat16Vector) + .withMetricType(MetricType.L2) + .withOutFields(Lists.newArrayList("*")) + .withTopK(10) + .withFloat16Vectors(CommonFunction.generateFloat16Vectors(CommonData.dim, 1)) + .withVectorFieldName(CommonData.defaultFloat16VectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) +// .withExpr(expr) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData(CommonData.defaultFloat16VectorField, 0).size(), 10); + } + + + @Test(description = "Search with bfloat16 vector", groups = {"Smoke"}) + public void searchWithBF16Vector() { + + // search + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithBf16Vector) + .withMetricType(MetricType.L2) + .withOutFields(Lists.newArrayList("*")) + .withTopK(3) + .withBFloat16Vectors(CommonFunction.generateBF16Vectors(CommonData.dim, 1)) + .withVectorFieldName(CommonData.defaultBF16VectorField) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) // .withExpr(expr) - .withConsistencyLevel(ConsistencyLevelEnum.STRONG) - .build(); - R searchResultsR = milvusClient.search(searchParam); - Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); - SearchResultsWrapper searchResultsWrapper = - new SearchResultsWrapper(searchResultsR.getData().getResults()); - Assert.assertTrue(searchResultsWrapper.getFieldData("str_array_field", 0).size()>=4); - } + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData(CommonData.defaultBF16VectorField, 0).size(), 3); + } + + @Test(description = "Search with sparse vector", groups = {"Smoke"}, dataProvider = "sparseIndex") + public void searchWithSparseVector(IndexType indexType) { + // search + Integer SEARCH_K = 100; // TopK + String SEARCH_PARAM = "{\"drop_ratio_search\":0.0,\"offset\":0}"; + List search_output_fields = Collections.singletonList("*"); + List> search_vectors = Lists.newArrayList(CommonFunction.generateSparseVector()); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithSparseVector) + .withMetricType(MetricType.IP) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withSparseFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultSparseVectorField) + .withParams(SEARCH_PARAM) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertTrue(searchResultsWrapper.getFieldData(CommonData.defaultSparseVectorField, 0).size() >= 1); + milvusClient.dropIndex(DropIndexParam.newBuilder().withCollectionName(collectionWithSparseVector).build()); + } + + @Test(description = "Search nq>1 with sparse vector", groups = {"Smoke"}, dataProvider = "sparseIndex") + public void searchMultiNQWithSparseVector(IndexType indexType) { + List fields = CommonFunction.generateDataWithSparseFloatVector(2000); + R insert = milvusClient.insert(InsertParam.newBuilder() + .withFields(fields) + .withCollectionName(collectionWithSparseVector) + .build()); + Assert.assertEquals(insert.getStatus().intValue(), 0); + CommonFunction.createIndexWithLoad(collectionWithSparseVector, indexType, MetricType.IP, CommonData.defaultSparseVectorField); + // search + Integer SEARCH_K = 100; // TopK + String SEARCH_PARAM = "{\"drop_ratio_search\":0.0}"; + List search_output_fields = Collections.singletonList("*"); + List> search_vectors = Lists.newArrayList(CommonFunction.generateSparseVector(), CommonFunction.generateSparseVector()); + SearchParam searchParam = + SearchParam.newBuilder() + .withCollectionName(collectionWithSparseVector) + .withMetricType(MetricType.IP) + .withOutFields(search_output_fields) + .withTopK(SEARCH_K) + .withSparseFloatVectors(search_vectors) + .withVectorFieldName(CommonData.defaultSparseVectorField) + .withParams(SEARCH_PARAM) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .build(); + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertTrue(searchResultsWrapper.getFieldData(CommonData.defaultSparseVectorField, 0).size() >= 1); + } + + @Test(description = "Search with multi vector", groups = {"Smoke"}) + public void searchWithMultiVector() { + // search + AnnSearchParam floatVSP = AnnSearchParam.newBuilder() + .withFloatVectors(CommonFunction.generateFloatVectors(1, CommonData.dim)) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withVectorFieldName(CommonData.defaultVectorField) + .withMetricType(MetricType.L2) + .withTopK(10).build(); + AnnSearchParam binaryVSP = AnnSearchParam.newBuilder() + .withBinaryVectors(CommonFunction.generateBinaryVectors(1, CommonData.dim)) + .withParams(CommonFunction.provideExtraParam(IndexType.BIN_FLAT)) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withMetricType(MetricType.HAMMING) + .withTopK(20).build(); + AnnSearchParam sparseVSP = AnnSearchParam.newBuilder() + .withSparseFloatVectors(Collections.singletonList(CommonFunction.generateSparseVector())) + .withParams(CommonFunction.provideExtraParam(IndexType.SPARSE_INVERTED_INDEX)) + .withVectorFieldName(CommonData.defaultSparseVectorField) + .withMetricType(MetricType.IP) + .withTopK(30).build(); + AnnSearchParam float16VSP = AnnSearchParam.newBuilder() + .withFloat16Vectors(CommonFunction.generateFloat16Vectors(CommonData.dim, 1)) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withVectorFieldName(CommonData.defaultFloat16VectorField) + .withMetricType(MetricType.L2) + .withTopK(30).build(); +/* AnnSearchParam bf16VSP= AnnSearchParam.newBuilder() + + .withParams(CommonFunction.provideExtraParam(IndexType.SPARSE_INVERTED_INDEX)) + .withVectorFieldName(CommonData.defaultBF16VectorField) + .withMetricType(MetricType.L2) + .withTopK(30).build();*/ + + HybridSearchParam hybridSearchParam = HybridSearchParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withOutFields(Lists.newArrayList(CommonData.defaultVectorField, + CommonData.defaultBinaryVectorField, + CommonData.defaultSparseVectorField, + CommonData.defaultFloat16VectorField/*, + CommonData.defaultBF16VectorField*/)) + .withTopK(40) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .addSearchRequest(floatVSP) + .addSearchRequest(binaryVSP) + .addSearchRequest(sparseVSP) + .addSearchRequest(float16VSP) +// .addSearchRequest(bf16VSP) + .withRanker(RRFRanker.newBuilder() + .withK(2) + .build()) + .build(); + R searchResultsR = milvusClient.hybridSearch(hybridSearchParam); + + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertTrue(searchResultsWrapper.getFieldData(CommonData.defaultSparseVectorField, 0).size() == 40); + } + + @Test(description = "Search nq>1 with multi vector", groups = {"Smoke"}) + public void searchNQWithMultiVector() { + // search + AnnSearchParam floatVSP = AnnSearchParam.newBuilder() + .withFloatVectors(CommonFunction.generateFloatVectors(2, CommonData.dim)) + .withParams(CommonFunction.provideExtraParam(IndexType.HNSW)) + .withVectorFieldName(CommonData.defaultVectorField) + .withMetricType(MetricType.L2) + .withTopK(10).build(); + AnnSearchParam binaryVSP = AnnSearchParam.newBuilder() + .withBinaryVectors(CommonFunction.generateBinaryVectors(2, CommonData.dim)) + .withParams(CommonFunction.provideExtraParam(IndexType.BIN_FLAT)) + .withVectorFieldName(CommonData.defaultBinaryVectorField) + .withMetricType(MetricType.HAMMING) + .withTopK(20).build(); + AnnSearchParam sparseVSP = AnnSearchParam.newBuilder() + .withSparseFloatVectors(Lists.newArrayList(CommonFunction.generateSparseVector(), CommonFunction.generateSparseVector())) + .withParams(CommonFunction.provideExtraParam(IndexType.SPARSE_INVERTED_INDEX)) + .withVectorFieldName(CommonData.defaultSparseVectorField) + .withMetricType(MetricType.IP) + .withTopK(30).build(); + + HybridSearchParam hybridSearchParam = HybridSearchParam.newBuilder() + .withCollectionName(collectionWithMultiVector) + .withOutFields(Lists.newArrayList(CommonData.defaultVectorField, CommonData.defaultBinaryVectorField, CommonData.defaultSparseVectorField)) + .withTopK(40) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .addSearchRequest(binaryVSP) + .addSearchRequest(sparseVSP) + .addSearchRequest(floatVSP) + .withRanker(RRFRanker.newBuilder() + .withK(2) + .build()) + .build(); + R searchResultsR = milvusClient.hybridSearch(hybridSearchParam); + + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertTrue(searchResultsWrapper.getFieldData(CommonData.defaultSparseVectorField, 0).size() == 40); + } + + + @DataProvider(name = "groupByTestData") // collection name, index type, metric type, vector field name,topK,expected + public Object[][] provideGroupByTestData() { + return new Object[][]{ + {collectionWithFloat16Vector, IndexType.HNSW, MetricType.L2, CommonData.defaultFloat16VectorField, 10, 1}, + {collectionWithSparseVector, IndexType.SPARSE_INVERTED_INDEX, MetricType.IP, CommonData.defaultSparseVectorField, 10, 1}, + {collectionWithBf16Vector, IndexType.HNSW, MetricType.L2, CommonData.defaultBF16VectorField, 10, 1}, + {collectionWithFloatVector,IndexType.HNSW,MetricType.L2,CommonData.defaultVectorField,10,1}, +// {collectionWithBinaryVector,IndexType.BIN_FLAT,MetricType.HAMMING,CommonData.defaultBinaryVectorField,10,1} + }; + + } + + @Test(description = "search with groupby", groups = {"Smoke"}, dataProvider = "groupByTestData") + public void groupByTest(String collectionName, IndexType indexType, MetricType metricType, String vectorFieldName, int topK, int expected) { + // search + SearchParam searchParam; + switch (vectorFieldName){ + case "Float16VectorField": + searchParam=SearchParam.newBuilder() + .withCollectionName(collectionName) + .withMetricType(metricType) + .withOutFields(Lists.newArrayList("*")) + .withGroupByFieldName("word_count") + .withTopK(topK) + .withVectorFieldName(vectorFieldName) + .withParams(CommonFunction.provideExtraParam(indexType)) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG) + .withFloat16Vectors(CommonFunction.generateFloat16Vectors(CommonData.dim, 1)) + .build(); + break; + case "SparseFloatVectorField": + searchParam=SearchParam.newBuilder() + .withCollectionName(collectionName) + .withMetricType(metricType) + .withOutFields(Lists.newArrayList("*")) + .withGroupByFieldName("word_count") + .withTopK(topK) + .withVectorFieldName(vectorFieldName) + .withParams(CommonFunction.provideExtraParam(indexType)) + .withConsistencyLevel(ConsistencyLevelEnum.STRONG).withSparseFloatVectors(Lists.newArrayList(CommonFunction.generateSparseVector())) + .build(); + break; + case "book_intro": + searchParam=SearchParam.newBuilder() + .withCollectionName(collectionName) + .withMetricType(metricType) + .withOutFields(Lists.newArrayList("*")) + .withGroupByFieldName("word_count") + .withTopK(topK) + .withVectorFieldName(vectorFieldName) + .withParams(CommonFunction.provideExtraParam(indexType)) + .withFloatVectors(CommonFunction.generateFloatVectors(1, CommonData.dim)) + .build(); + break; + case "BinaryVectorFieldAutoTest": + searchParam=SearchParam.newBuilder() + .withCollectionName(collectionName) + .withMetricType(metricType) + .withOutFields(Lists.newArrayList("*")) + .withGroupByFieldName("word_count") + .withTopK(topK) + .withVectorFieldName(vectorFieldName) + .withParams(CommonFunction.provideExtraParam(indexType)) + .withBinaryVectors(CommonFunction.generateBinaryVectors(1, CommonData.dim)) + .build(); + break; + case "BF16VectorField": + searchParam=SearchParam.newBuilder() + .withCollectionName(collectionName) + .withMetricType(metricType) + .withOutFields(Lists.newArrayList("*")) + .withGroupByFieldName("word_count") + .withTopK(topK) + .withVectorFieldName(vectorFieldName) + .withParams(CommonFunction.provideExtraParam(indexType)) + .withBFloat16Vectors(CommonFunction.generateBF16Vectors(CommonData.dim, 1)) + .build(); + break; + default: + throw new IllegalStateException("Unexpected value: " + vectorFieldName); + } + R searchResultsR = milvusClient.search(searchParam); + Assert.assertEquals(searchResultsR.getStatus().intValue(), 0); + SearchResultsWrapper searchResultsWrapper = + new SearchResultsWrapper(searchResultsR.getData().getResults()); + Assert.assertEquals(searchResultsWrapper.getFieldData("word_count", 0).size(), expected); + } + + } diff --git a/tests/milvustest/src/test/java/com/zilliz/milvustest/segment/GetQuerySegmentInfoTest.java b/tests/milvustest/src/test/java/com/zilliz/milvustest/segment/GetQuerySegmentInfoTest.java index 1b7398736..01a654e5a 100644 --- a/tests/milvustest/src/test/java/com/zilliz/milvustest/segment/GetQuerySegmentInfoTest.java +++ b/tests/milvustest/src/test/java/com/zilliz/milvustest/segment/GetQuerySegmentInfoTest.java @@ -36,7 +36,7 @@ public void getQuerySegmentInfoTest() { .build()); System.out.println(responseR.getData()); Assert.assertEquals(responseR.getStatus().intValue(), 0); - Assert.assertTrue(responseR.getData().getInfos(0).getNumRows()>1); +// Assert.assertTrue(responseR.getData().getInfos(0).getNumRows()>1); Assert.assertTrue(responseR.getData().getInfosCount()>=2); }