浏览代码

Support multiple fields search (#841)

Signed-off-by: yhmo <yihua.mo@zilliz.com>
groot 1 年之前
父节点
当前提交
ab46ffcfdb
共有 100 个文件被更改,包括 3168 次插入280 次删除
  1. 29 30
      examples/main/java/io/milvus/BinaryVectorExample.java
  2. 33 44
      examples/main/java/io/milvus/BulkWriterExample.java
  3. 120 0
      examples/main/java/io/milvus/CommonUtils.java
  4. 10 41
      examples/main/java/io/milvus/Float16VectorExample.java
  5. 32 67
      examples/main/java/io/milvus/GeneralExample.java
  6. 11 33
      examples/main/java/io/milvus/HighLevelExample.java
  7. 314 0
      examples/main/java/io/milvus/HybridSearchExample.java
  8. 0 1
      examples/main/java/io/milvus/RBACExample.java
  9. 0 1
      examples/main/java/io/milvus/SimpleExample.java
  10. 28 30
      examples/main/java/io/milvus/SparseVectorExample.java
  11. 3 10
      examples/main/java/io/milvus/TLSExample.java
  12. 19 0
      src/main/java/io/milvus/bulkwriter/Buffer.java
  13. 19 0
      src/main/java/io/milvus/bulkwriter/BulkWriter.java
  14. 19 0
      src/main/java/io/milvus/bulkwriter/CloudImport.java
  15. 19 0
      src/main/java/io/milvus/bulkwriter/LocalBulkWriter.java
  16. 19 0
      src/main/java/io/milvus/bulkwriter/RemoteBulkWriter.java
  17. 19 0
      src/main/java/io/milvus/bulkwriter/common/clientenum/BulkFileType.java
  18. 19 0
      src/main/java/io/milvus/bulkwriter/common/clientenum/CloudStorage.java
  19. 19 0
      src/main/java/io/milvus/bulkwriter/common/clientenum/TypeSize.java
  20. 19 0
      src/main/java/io/milvus/bulkwriter/common/utils/GeneratorUtils.java
  21. 19 0
      src/main/java/io/milvus/bulkwriter/common/utils/ImportUtils.java
  22. 19 0
      src/main/java/io/milvus/bulkwriter/common/utils/ParquetReaderUtils.java
  23. 19 0
      src/main/java/io/milvus/bulkwriter/common/utils/ParquetUtils.java
  24. 19 0
      src/main/java/io/milvus/bulkwriter/connect/AzureConnectParam.java
  25. 19 0
      src/main/java/io/milvus/bulkwriter/connect/S3ConnectParam.java
  26. 19 0
      src/main/java/io/milvus/bulkwriter/connect/StorageConnectParam.java
  27. 19 0
      src/main/java/io/milvus/bulkwriter/response/BulkImportResponse.java
  28. 19 0
      src/main/java/io/milvus/bulkwriter/response/GetImportProgressResponse.java
  29. 19 0
      src/main/java/io/milvus/bulkwriter/response/ListImportJobsResponse.java
  30. 19 0
      src/main/java/io/milvus/bulkwriter/response/RestfulResponse.java
  31. 19 0
      src/main/java/io/milvus/bulkwriter/storage/StorageClient.java
  32. 19 0
      src/main/java/io/milvus/bulkwriter/storage/client/AzureStorageClient.java
  33. 19 0
      src/main/java/io/milvus/bulkwriter/storage/client/MinioStorageClient.java
  34. 68 0
      src/main/java/io/milvus/client/AbstractMilvusGrpcClient.java
  35. 16 0
      src/main/java/io/milvus/client/MilvusClient.java
  36. 10 0
      src/main/java/io/milvus/client/MilvusMultiServiceClient.java
  37. 5 0
      src/main/java/io/milvus/client/MilvusServiceClient.java
  38. 19 0
      src/main/java/io/milvus/common/clientenum/ConsistencyLevelEnum.java
  39. 19 0
      src/main/java/io/milvus/common/constant/MilvusClientConstant.java
  40. 19 0
      src/main/java/io/milvus/common/utils/ExceptionUtils.java
  41. 19 0
      src/main/java/io/milvus/common/utils/JacksonUtils.java
  42. 19 0
      src/main/java/io/milvus/common/utils/URLParser.java
  43. 19 0
      src/main/java/io/milvus/common/utils/VectorUtils.java
  44. 19 0
      src/main/java/io/milvus/connection/ClusterFactory.java
  45. 19 0
      src/main/java/io/milvus/connection/ClusterListener.java
  46. 19 0
      src/main/java/io/milvus/connection/Listener.java
  47. 19 0
      src/main/java/io/milvus/connection/QueryNodeListener.java
  48. 19 0
      src/main/java/io/milvus/connection/ServerMonitor.java
  49. 19 0
      src/main/java/io/milvus/connection/ServerSetting.java
  50. 19 0
      src/main/java/io/milvus/param/LogLevel.java
  51. 19 0
      src/main/java/io/milvus/param/MultiConnectParam.java
  52. 128 19
      src/main/java/io/milvus/param/ParamUtils.java
  53. 19 0
      src/main/java/io/milvus/param/QueryNodeSingleSearch.java
  54. 19 0
      src/main/java/io/milvus/param/ServerAddress.java
  55. 19 0
      src/main/java/io/milvus/param/alias/AlterAliasParam.java
  56. 19 0
      src/main/java/io/milvus/param/alias/CreateAliasParam.java
  57. 19 0
      src/main/java/io/milvus/param/alias/DropAliasParam.java
  58. 19 0
      src/main/java/io/milvus/param/alias/ListAliasesParam.java
  59. 19 0
      src/main/java/io/milvus/param/collection/FlushParam.java
  60. 19 0
      src/main/java/io/milvus/param/control/GetCompactionPlansParam.java
  61. 19 0
      src/main/java/io/milvus/param/control/GetCompactionStateParam.java
  62. 19 0
      src/main/java/io/milvus/param/control/GetFlushAllStateParam.java
  63. 19 0
      src/main/java/io/milvus/param/control/GetFlushStateParam.java
  64. 19 0
      src/main/java/io/milvus/param/control/GetReplicasParam.java
  65. 19 0
      src/main/java/io/milvus/param/control/ManualCompactParam.java
  66. 19 0
      src/main/java/io/milvus/param/credential/CreateCredentialParam.java
  67. 19 0
      src/main/java/io/milvus/param/credential/DeleteCredentialParam.java
  68. 19 0
      src/main/java/io/milvus/param/credential/ListCredUsersParam.java
  69. 19 0
      src/main/java/io/milvus/param/credential/UpdateCredentialParam.java
  70. 219 0
      src/main/java/io/milvus/param/dml/AnnSearchParam.java
  71. 236 0
      src/main/java/io/milvus/param/dml/HybridSearchParam.java
  72. 19 0
      src/main/java/io/milvus/param/dml/UpsertParam.java
  73. 27 0
      src/main/java/io/milvus/param/dml/ranker/BaseRanker.java
  74. 94 0
      src/main/java/io/milvus/param/dml/ranker/RRFRanker.java
  75. 91 0
      src/main/java/io/milvus/param/dml/ranker/WeightedRanker.java
  76. 19 0
      src/main/java/io/milvus/param/role/AddUserToRoleParam.java
  77. 19 0
      src/main/java/io/milvus/param/role/CreateRoleParam.java
  78. 19 0
      src/main/java/io/milvus/param/role/DropRoleParam.java
  79. 19 0
      src/main/java/io/milvus/param/role/GrantRolePrivilegeParam.java
  80. 19 0
      src/main/java/io/milvus/param/role/RemoveUserFromRoleParam.java
  81. 19 0
      src/main/java/io/milvus/param/role/RevokeRolePrivilegeParam.java
  82. 19 0
      src/main/java/io/milvus/param/role/SelectGrantForRoleAndObjectParam.java
  83. 19 0
      src/main/java/io/milvus/param/role/SelectGrantForRoleParam.java
  84. 19 0
      src/main/java/io/milvus/param/role/SelectRoleParam.java
  85. 19 0
      src/main/java/io/milvus/param/role/SelectUserParam.java
  86. 19 0
      src/main/java/io/milvus/response/BulkInsertResponseWrapper.java
  87. 39 0
      src/main/java/io/milvus/response/DescCollResponseWrapper.java
  88. 19 0
      src/main/java/io/milvus/response/DescIndexResponseWrapper.java
  89. 19 0
      src/main/java/io/milvus/response/FieldDataWrapper.java
  90. 19 0
      src/main/java/io/milvus/response/GetBulkInsertStateWrapper.java
  91. 19 0
      src/main/java/io/milvus/response/GetCollStatResponseWrapper.java
  92. 19 0
      src/main/java/io/milvus/response/GetPartStatResponseWrapper.java
  93. 19 0
      src/main/java/io/milvus/response/MutationResultWrapper.java
  94. 19 0
      src/main/java/io/milvus/response/QueryResultsWrapper.java
  95. 19 0
      src/main/java/io/milvus/response/SearchResultsWrapper.java
  96. 19 0
      src/main/java/io/milvus/response/ShowCollResponseWrapper.java
  97. 19 0
      src/main/java/io/milvus/response/ShowPartResponseWrapper.java
  98. 19 0
      src/main/java/io/milvus/response/basic/RowRecordWrapper.java
  99. 162 4
      src/test/java/io/milvus/client/MilvusClientDockerTest.java
  100. 49 0
      src/test/java/io/milvus/client/MilvusServiceClientTest.java

+ 29 - 30
examples/main/java/io/milvus/BinaryVectorExample.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import io.milvus.client.MilvusServiceClient;
 import io.milvus.common.clientenum.ConsistencyLevelEnum;
 import io.milvus.grpc.*;
@@ -20,27 +39,7 @@ public class BinaryVectorExample {
     private static final String VECTOR_FIELD = "vector";
 
     private static final Integer VECTOR_DIM = 512;
-
-    private static List<ByteBuffer> generateVectors(int count) {
-        Random ran = new Random();
-        List<ByteBuffer> vectors = new ArrayList<>();
-        int byteCount = VECTOR_DIM / 8;
-        for (int n = 0; n < count; ++n) {
-            ByteBuffer vector = ByteBuffer.allocate(byteCount);
-            for (int i = 0; i < byteCount; ++i) {
-                vector.put((byte) ran.nextInt(Byte.MAX_VALUE));
-            }
-            vectors.add(vector);
-        }
-        return vectors;
-
-    }
-
-    private static void handleResponseStatus(R<?> r) {
-        if (r.getStatus() != R.Status.Success.getCode()) {
-            throw new RuntimeException(r.getMessage());
-        }
-    }
+    
 
     public static void main(String[] args) {
         // Connect to Milvus server. Replace the "localhost" and port with your Milvus server address.
@@ -53,7 +52,7 @@ public class BinaryVectorExample {
         R<Boolean> hasR = milvusClient.hasCollection(HasCollectionParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(hasR);
+        CommonUtils.handleResponseStatus(hasR);
         if (hasR.getData()) {
             milvusClient.dropCollection(DropCollectionParam.newBuilder()
                     .withCollectionName(COLLECTION_NAME)
@@ -81,7 +80,7 @@ public class BinaryVectorExample {
                 .withConsistencyLevel(ConsistencyLevelEnum.STRONG)
                 .withFieldTypes(fieldsSchema)
                 .build());
-        handleResponseStatus(ret);
+        CommonUtils.handleResponseStatus(ret);
         System.out.println("Collection created");
 
         // Insert entities
@@ -90,7 +89,7 @@ public class BinaryVectorExample {
         for (long i = 0L; i < rowCount; ++i) {
             ids.add(i);
         }
-        List<ByteBuffer> vectors = generateVectors(rowCount);
+        List<ByteBuffer> vectors = CommonUtils.generateBinaryVectors(VECTOR_DIM, rowCount);
 
         List<InsertParam.Field> fieldsInsert = new ArrayList<>();
         fieldsInsert.add(new InsertParam.Field(ID_FIELD, ids));
@@ -102,14 +101,14 @@ public class BinaryVectorExample {
                 .build();
 
         R<MutationResult> insertR = milvusClient.insert(insertParam);
-        handleResponseStatus(insertR);
+        CommonUtils.handleResponseStatus(insertR);
 
         // Flush the data to storage for testing purpose
         // Note that no need to manually call flush interface in practice
         R<FlushResponse> flushR = milvusClient.flush(FlushParam.newBuilder().
                 addCollectionName(COLLECTION_NAME).
                 build());
-        handleResponseStatus(flushR);
+        CommonUtils.handleResponseStatus(flushR);
         System.out.println("Entities inserted");
 
         // Specify an index type on the vector field.
@@ -120,14 +119,14 @@ public class BinaryVectorExample {
                 .withMetricType(MetricType.HAMMING)
                 .withExtraParam("{\"nlist\":64}")
                 .build());
-        handleResponseStatus(ret);
+        CommonUtils.handleResponseStatus(ret);
         System.out.println("Index created");
 
         // Call loadCollection() to enable automatically loading data into memory for searching
         ret = milvusClient.loadCollection(LoadCollectionParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(ret);
+        CommonUtils.handleResponseStatus(ret);
         System.out.println("Collection loaded");
 
         // Pick some vectors from the inserted vectors to search
@@ -145,7 +144,7 @@ public class BinaryVectorExample {
                     .addOutField(VECTOR_FIELD)
                     .withParams("{\"nprobe\":16}")
                     .build());
-            handleResponseStatus(searchRet);
+            CommonUtils.handleResponseStatus(searchRet);
 
             // The search() allows multiple target vectors to search in a batch.
             // Here we only input one vector to search, get the result of No.0 vector to check
@@ -175,7 +174,7 @@ public class BinaryVectorExample {
                 .withExpr(String.format("id == %d", n))
                 .addOutField(VECTOR_FIELD)
                 .build());
-        handleResponseStatus(queryR);
+        CommonUtils.handleResponseStatus(queryR);
         QueryResultsWrapper queryWrapper = new QueryResultsWrapper(queryR.getData());
         FieldDataWrapper field = queryWrapper.getFieldWrapper(VECTOR_FIELD);
         List<?> r = field.getFieldData();

+ 33 - 44
examples/main/java/io/milvus/BulkWriterExample.java

@@ -1,4 +1,21 @@
-package io.milvus;
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
 
 import com.alibaba.fastjson.JSONObject;
 import com.fasterxml.jackson.annotation.JsonProperty;
@@ -7,12 +24,12 @@ import com.fasterxml.jackson.dataformat.csv.CsvSchema;
 import com.google.common.collect.Lists;
 import com.google.gson.Gson;
 import com.google.gson.reflect.TypeToken;
-import io.milvus.bulkwriter.BulkWriter;
-import io.milvus.bulkwriter.CloudImport;
-import io.milvus.bulkwriter.LocalBulkWriter;
-import io.milvus.bulkwriter.LocalBulkWriterParam;
-import io.milvus.bulkwriter.RemoteBulkWriter;
-import io.milvus.bulkwriter.RemoteBulkWriterParam;
+import io.milvus.bulkwriter.*;
+import io.milvus.bulkwriter.common.clientenum.BulkFileType;
+import io.milvus.bulkwriter.common.clientenum.CloudStorage;
+import io.milvus.bulkwriter.common.utils.GeneratorUtils;
+import io.milvus.bulkwriter.common.utils.ImportUtils;
+import io.milvus.bulkwriter.common.utils.ParquetReaderUtils;
 import io.milvus.bulkwriter.connect.AzureConnectParam;
 import io.milvus.bulkwriter.connect.S3ConnectParam;
 import io.milvus.bulkwriter.connect.StorageConnectParam;
@@ -21,34 +38,12 @@ import io.milvus.bulkwriter.response.GetImportProgressResponse;
 import io.milvus.bulkwriter.response.ListImportJobsResponse;
 import io.milvus.client.MilvusClient;
 import io.milvus.client.MilvusServiceClient;
-import io.milvus.bulkwriter.common.clientenum.BulkFileType;
-import io.milvus.bulkwriter.common.clientenum.CloudStorage;
 import io.milvus.common.utils.ExceptionUtils;
-import io.milvus.bulkwriter.common.utils.GeneratorUtils;
-import io.milvus.bulkwriter.common.utils.ImportUtils;
-import io.milvus.bulkwriter.common.utils.ParquetReaderUtils;
-import io.milvus.grpc.DataType;
-import io.milvus.grpc.GetCollectionStatisticsResponse;
-import io.milvus.grpc.GetImportStateResponse;
-import io.milvus.grpc.ImportResponse;
-import io.milvus.grpc.ImportState;
-import io.milvus.grpc.KeyValuePair;
-import io.milvus.grpc.QueryResults;
-import io.milvus.param.ConnectParam;
-import io.milvus.param.IndexType;
-import io.milvus.param.MetricType;
-import io.milvus.param.R;
-import io.milvus.param.RpcStatus;
+import io.milvus.grpc.*;
+import io.milvus.param.*;
 import io.milvus.param.bulkinsert.BulkInsertParam;
 import io.milvus.param.bulkinsert.GetBulkInsertStateParam;
-import io.milvus.param.collection.CollectionSchemaParam;
-import io.milvus.param.collection.CreateCollectionParam;
-import io.milvus.param.collection.DropCollectionParam;
-import io.milvus.param.collection.FieldType;
-import io.milvus.param.collection.FlushParam;
-import io.milvus.param.collection.GetCollectionStatisticsParam;
-import io.milvus.param.collection.HasCollectionParam;
-import io.milvus.param.collection.LoadCollectionParam;
+import io.milvus.param.collection.*;
 import io.milvus.param.dml.QueryParam;
 import io.milvus.param.index.CreateIndexParam;
 import io.milvus.response.GetCollStatResponseWrapper;
@@ -68,20 +63,14 @@ import java.util.List;
 import java.util.Optional;
 import java.util.concurrent.TimeUnit;
 
-import static io.milvus.BulkWriterExample.MilvusConsts.HOST;
-import static io.milvus.BulkWriterExample.MilvusConsts.PORT;
-import static io.milvus.BulkWriterExample.MilvusConsts.USER_NAME;
-
 
 public class BulkWriterExample {
-
     // milvus
-    public static class MilvusConsts {
-        public static final String HOST = "127.0.0.1";
-        public static final Integer PORT = 19530;
-        public static final String USER_NAME = "user.name";
-        public static final String PASSWORD = "password";
-    }
+    public static final String HOST = "127.0.0.1";
+    public static final Integer PORT = 19530;
+    public static final String USER_NAME = "user.name";
+    public static final String PASSWORD = "password";
+
 
     /**
      * If you need to transfer the files generated by bulkWriter to the corresponding remote storage (AWS S3, GCP GCS, Azure Blob, Aliyun OSS, Tencent Cloud TOS),
@@ -164,7 +153,7 @@ public class BulkWriterExample {
         ConnectParam connectParam = ConnectParam.newBuilder()
                 .withHost(HOST)
                 .withPort(PORT)
-                .withAuthorization(USER_NAME, MilvusConsts.PASSWORD)
+                .withAuthorization(USER_NAME, PASSWORD)
                 .withSecure(true)
                 .build();
         milvusClient = new MilvusServiceClient(connectParam);

+ 120 - 0
examples/main/java/io/milvus/CommonUtils.java

@@ -0,0 +1,120 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import io.milvus.param.R;
+import org.tensorflow.ndarray.buffer.ByteDataBuffer;
+import org.tensorflow.types.TBfloat16;
+import org.tensorflow.types.TFloat16;
+
+import java.nio.ByteBuffer;
+import java.util.*;
+
+public class CommonUtils {
+
+    public static void handleResponseStatus(R<?> r) {
+        if (r.getStatus() != R.Status.Success.getCode()) {
+            throw new RuntimeException(r.getMessage());
+        }
+    }
+
+    public static List<Float> generateFloatVector(int dimension) {
+        Random ran = new Random();
+        List<Float> vector = new ArrayList<>();
+        for (int i = 0; i < dimension; ++i) {
+            vector.add(ran.nextFloat());
+        }
+        return vector;
+    }
+
+    public static List<List<Float>> generateFloatVectors(int dimension, int count) {
+        List<List<Float>> vectors = new ArrayList<>();
+        for (int n = 0; n < count; ++n) {
+            List<Float> vector = generateFloatVector(dimension);
+            vectors.add(vector);
+        }
+        return vectors;
+    }
+
+    public static ByteBuffer generateBinaryVector(int dimension) {
+        Random ran = new Random();
+        int byteCount = dimension / 8;
+        ByteBuffer vector = ByteBuffer.allocate(byteCount);
+        for (int i = 0; i < byteCount; ++i) {
+            vector.put((byte) ran.nextInt(Byte.MAX_VALUE));
+        }
+        return vector;
+    }
+
+    public static List<ByteBuffer> generateBinaryVectors(int dimension, int count) {
+        List<ByteBuffer> vectors = new ArrayList<>();
+        for (int n = 0; n < count; ++n) {
+            ByteBuffer vector = generateBinaryVector(dimension);
+            vectors.add(vector);
+        }
+        return vectors;
+    }
+
+    public static ByteBuffer generateFloat16Vector(int dimension, boolean bfloat16) {
+        Random ran = new Random();
+        int byteCount = dimension*2;
+        ByteBuffer vector = ByteBuffer.allocate(byteCount);
+        for (int i = 0; i < dimension; ++i) {
+            ByteDataBuffer bf;
+            if (bfloat16) {
+                TFloat16 tt = TFloat16.scalarOf((float)ran.nextInt(dimension));
+                bf = tt.asRawTensor().data();
+            } else {
+                TBfloat16 tt = TBfloat16.scalarOf((float)ran.nextInt(dimension));
+                bf = tt.asRawTensor().data();
+            }
+            vector.put(bf.getByte(0));
+            vector.put(bf.getByte(1));
+        }
+        return vector;
+    }
+
+    public static List<ByteBuffer> generateFloat16Vectors(int dimension, int count, boolean bfloat16) {
+        List<ByteBuffer> vectors = new ArrayList<>();
+        for (int n = 0; n < count; ++n) {
+            ByteBuffer vector = generateFloat16Vector(dimension, bfloat16);
+            vectors.add(vector);
+        }
+        return vectors;
+    }
+
+    public static SortedMap<Long, Float> generateSparseVector() {
+        Random ran = new Random();
+        SortedMap<Long, Float> sparse = new TreeMap<>();
+        int dim = ran.nextInt(10) + 1;
+        for (int i = 0; i < dim; ++i) {
+            sparse.put((long)ran.nextInt(1000000), ran.nextFloat());
+        }
+        return sparse;
+    }
+
+    public static List<SortedMap<Long, Float>> generateSparseVectors(int count) {
+        List<SortedMap<Long, Float>> vectors = new ArrayList<>();
+        for (int n = 0; n < count; ++n) {
+            SortedMap<Long, Float> sparse = generateSparseVector();
+            vectors.add(sparse);
+        }
+        return vectors;
+    }
+
+}

+ 10 - 41
examples/main/java/io/milvus/Float16VectorExample.java

@@ -17,8 +17,6 @@
  * under the License.
  */
 
-package io.milvus;
-
 import io.milvus.client.MilvusServiceClient;
 import io.milvus.common.clientenum.ConsistencyLevelEnum;
 import io.milvus.grpc.*;
@@ -40,36 +38,7 @@ public class Float16VectorExample {
     private static final String ID_FIELD = "id";
     private static final String VECTOR_FIELD = "vector";
     private static final Integer VECTOR_DIM = 128;
-
-    private static List<ByteBuffer> generateVectors(int count, boolean bfloat16) {
-        Random ran = new Random();
-        List<ByteBuffer> 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) {
-                ByteDataBuffer bf = null;
-                if (bfloat16) {
-                    TFloat16 tt = TFloat16.scalarOf((float)ran.nextInt(VECTOR_DIM));
-                    bf = tt.asRawTensor().data();
-                } else {
-                    TBfloat16 tt = TBfloat16.scalarOf((float)ran.nextInt(VECTOR_DIM));
-                    bf = tt.asRawTensor().data();
-                }
-                vector.put(bf.getByte(0));
-                vector.put(bf.getByte(1));
-            }
-            vectors.add(vector);
-        }
-
-        return vectors;
-    }
-
-    private static void handleResponseStatus(R<?> r) {
-        if (r.getStatus() != R.Status.Success.getCode()) {
-            throw new RuntimeException(r.getMessage());
-        }
-    }
+    
 
     private static void testFloat16(boolean bfloat16) {
         DataType dataType = bfloat16 ? DataType.BFloat16Vector : DataType.Float16Vector;
@@ -85,7 +54,7 @@ public class Float16VectorExample {
         R<Boolean> hasR = milvusClient.hasCollection(HasCollectionParam.newBuilder()
                                     .withCollectionName(COLLECTION_NAME)
                                     .build());
-        handleResponseStatus(hasR);
+        CommonUtils.handleResponseStatus(hasR);
         if (hasR.getData()) {
             milvusClient.dropCollection(DropCollectionParam.newBuilder()
                     .withCollectionName(COLLECTION_NAME)
@@ -113,7 +82,7 @@ public class Float16VectorExample {
                 .withConsistencyLevel(ConsistencyLevelEnum.STRONG)
                 .withFieldTypes(fieldsSchema)
                 .build());
-        handleResponseStatus(ret);
+        CommonUtils.handleResponseStatus(ret);
         System.out.println("Collection created");
 
         // Insert entities
@@ -122,7 +91,7 @@ public class Float16VectorExample {
         for (long i = 0L; i < rowCount; ++i) {
             ids.add(i);
         }
-        List<ByteBuffer> vectors = generateVectors(rowCount, bfloat16);
+        List<ByteBuffer> vectors = CommonUtils.generateFloat16Vectors(VECTOR_DIM, rowCount, bfloat16);
 
         List<InsertParam.Field> fieldsInsert = new ArrayList<>();
         fieldsInsert.add(new InsertParam.Field(ID_FIELD, ids));
@@ -134,14 +103,14 @@ public class Float16VectorExample {
                 .build();
 
         R<MutationResult> insertR = milvusClient.insert(insertParam);
-        handleResponseStatus(insertR);
+        CommonUtils.handleResponseStatus(insertR);
 
         // Flush the data to storage for testing purpose
         // Note that no need to manually call flush interface in practice
         R<FlushResponse> flushR = milvusClient.flush(FlushParam.newBuilder().
                 addCollectionName(COLLECTION_NAME).
                 build());
-        handleResponseStatus(flushR);
+        CommonUtils.handleResponseStatus(flushR);
         System.out.println("Entities inserted");
 
         // Specify an index type on the vector field.
@@ -152,14 +121,14 @@ public class Float16VectorExample {
                 .withMetricType(MetricType.L2)
                 .withExtraParam("{\"nlist\":128}")
                 .build());
-        handleResponseStatus(ret);
+        CommonUtils.handleResponseStatus(ret);
         System.out.println("Index created");
 
         // Call loadCollection() to enable automatically loading data into memory for searching
         ret = milvusClient.loadCollection(LoadCollectionParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(ret);
+        CommonUtils.handleResponseStatus(ret);
         System.out.println("Collection loaded");
 
         // Pick some vectors from the inserted vectors to search
@@ -177,7 +146,7 @@ public class Float16VectorExample {
                     .addOutField(VECTOR_FIELD)
                     .withParams("{\"nprobe\":32}")
                     .build());
-            handleResponseStatus(searchRet);
+            CommonUtils.handleResponseStatus(searchRet);
 
             // The search() allows multiple target vectors to search in a batch.
             // Here we only input one vector to search, get the result of No.0 vector to check
@@ -201,7 +170,7 @@ public class Float16VectorExample {
                 .withExpr(String.format("id == %d", n))
                 .addOutField(VECTOR_FIELD)
                 .build());
-        handleResponseStatus(queryR);
+        CommonUtils.handleResponseStatus(queryR);
         QueryResultsWrapper queryWrapper = new QueryResultsWrapper(queryR.getData());
         FieldDataWrapper field = queryWrapper.getFieldWrapper(VECTOR_FIELD);
         List<?> r = field.getFieldData();

+ 32 - 67
examples/main/java/io/milvus/GeneralExample.java

@@ -17,19 +17,18 @@
  * under the License.
  */
 
-package io.milvus;
-
 import com.alibaba.fastjson.JSONObject;
-import com.google.protobuf.ByteString;
 import io.milvus.client.MilvusClient;
 import io.milvus.client.MilvusServiceClient;
 import io.milvus.common.clientenum.ConsistencyLevelEnum;
-import io.milvus.common.utils.JacksonUtils;
 import io.milvus.grpc.*;
 import io.milvus.param.*;
 import io.milvus.param.collection.*;
 import io.milvus.param.control.ManualCompactParam;
-import io.milvus.param.dml.*;
+import io.milvus.param.dml.DeleteParam;
+import io.milvus.param.dml.InsertParam;
+import io.milvus.param.dml.QueryParam;
+import io.milvus.param.dml.SearchParam;
 import io.milvus.param.index.*;
 import io.milvus.param.partition.*;
 import io.milvus.response.*;
@@ -37,12 +36,6 @@ import io.milvus.response.*;
 import java.util.*;
 import java.util.concurrent.TimeUnit;
 
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Note:
-// Due do a technical limitation, the Milvus 2.0 not allow to create multi-vector-fields within a collection.
-// So this example only create a single vector field in the collection, but we suppose the next version
-// should support this function.
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class GeneralExample {
     private static final MilvusClient milvusClient;
@@ -71,12 +64,7 @@ public class GeneralExample {
 
     private static final Integer SEARCH_K = 5;
     private static final String SEARCH_PARAM = "{\"nprobe\":10}";
-
-    private void handleResponseStatus(R<?> r) {
-        if (r.getStatus() != R.Status.Success.getCode()) {
-            throw new RuntimeException(r.getMessage());
-        }
-    }
+    
 
     private R<RpcStatus> createCollection(long timeoutMilliseconds) {
         System.out.println("========== createCollection() ==========");
@@ -112,7 +100,7 @@ public class GeneralExample {
                 .build();
         R<RpcStatus> response = milvusClient.withTimeout(timeoutMilliseconds, TimeUnit.MILLISECONDS)
                 .createCollection(createCollectionReq);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -131,7 +119,7 @@ public class GeneralExample {
         R<Boolean> response = milvusClient.hasCollection(HasCollectionParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response.getData().booleanValue();
     }
@@ -141,7 +129,7 @@ public class GeneralExample {
         R<RpcStatus> response = milvusClient.loadCollection(LoadCollectionParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -151,7 +139,7 @@ public class GeneralExample {
         R<RpcStatus> response = milvusClient.releaseCollection(ReleaseCollectionParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -161,7 +149,7 @@ public class GeneralExample {
         R<DescribeCollectionResponse> response = milvusClient.describeCollection(DescribeCollectionParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         DescCollResponseWrapper wrapper = new DescCollResponseWrapper(response.getData());
         System.out.println(wrapper.toString());
         return response;
@@ -177,7 +165,7 @@ public class GeneralExample {
                 GetCollectionStatisticsParam.newBuilder()
                         .withCollectionName(COLLECTION_NAME)
                         .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         GetCollStatResponseWrapper wrapper = new GetCollStatResponseWrapper(response.getData());
         System.out.println("Collection row count: " + wrapper.getRowCount());
         return response;
@@ -187,7 +175,7 @@ public class GeneralExample {
         System.out.println("========== showCollections() ==========");
         R<ShowCollectionsResponse> response = milvusClient.showCollections(ShowCollectionsParam.newBuilder()
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -198,7 +186,7 @@ public class GeneralExample {
                 .withCollectionName(COLLECTION_NAME)
                 .withPartitionName(partitionName)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -209,7 +197,7 @@ public class GeneralExample {
                 .withCollectionName(COLLECTION_NAME)
                 .withPartitionName(partitionName)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -220,7 +208,7 @@ public class GeneralExample {
                 .withCollectionName(COLLECTION_NAME)
                 .withPartitionName(partitionName)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -231,7 +219,7 @@ public class GeneralExample {
                 .withCollectionName(COLLECTION_NAME)
                 .addPartitionName(partitionName)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -241,7 +229,7 @@ public class GeneralExample {
         R<ShowPartitionsResponse> response = milvusClient.showPartitions(ShowPartitionsParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -255,7 +243,7 @@ public class GeneralExample {
                 .withIndexType(IndexType.STL_SORT)
                 .withSyncMode(Boolean.TRUE)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
 
         // create index for vector field
         response = milvusClient.createIndex(CreateIndexParam.newBuilder()
@@ -267,7 +255,7 @@ public class GeneralExample {
                 .withExtraParam(INDEX_PARAM)
                 .withSyncMode(Boolean.TRUE)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -278,7 +266,7 @@ public class GeneralExample {
                 .withCollectionName(COLLECTION_NAME)
                 .withIndexName(INDEX_NAME)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -289,7 +277,7 @@ public class GeneralExample {
                 .withCollectionName(COLLECTION_NAME)
                 .withIndexName(INDEX_NAME)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -300,7 +288,7 @@ public class GeneralExample {
                 .withCollectionName(COLLECTION_NAME)
                 .withIndexName(INDEX_NAME)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -312,7 +300,7 @@ public class GeneralExample {
                         .withCollectionName(COLLECTION_NAME)
                         .withIndexName(INDEX_NAME)
                         .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -325,7 +313,7 @@ public class GeneralExample {
                 .withExpr(expr)
                 .build();
         R<MutationResult> response = milvusClient.delete(build);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response.getData());
         return response;
     }
@@ -335,7 +323,7 @@ public class GeneralExample {
         long begin = System.currentTimeMillis();
 
         List<String> outFields = Collections.singletonList(AGE_FIELD);
-        List<List<Float>> vectors = generateFloatVectors(5);
+        List<List<Float>> vectors = CommonUtils.generateFloatVectors(VECTOR_DIM, 5);
 
         SearchParam searchParam = SearchParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
@@ -354,7 +342,7 @@ public class GeneralExample {
         long cost = (end - begin);
         System.out.println("Search time cost: " + cost + "ms");
 
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         SearchResultsWrapper wrapper = new SearchResultsWrapper(response.getData().getResults());
         for (int i = 0; i < vectors.size(); ++i) {
             System.out.println("Search result of No." + i);
@@ -376,7 +364,7 @@ public class GeneralExample {
                 .withOutFields(fields)
                 .build();
         R<QueryResults> response = milvusClient.query(test);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         QueryResultsWrapper wrapper = new QueryResultsWrapper(response.getData());
         System.out.println(ID_FIELD + ":" + wrapper.getFieldWrapper(ID_FIELD).getFieldData().toString());
         System.out.println(AGE_FIELD + ":" + wrapper.getFieldWrapper(AGE_FIELD).getFieldData().toString());
@@ -389,13 +377,13 @@ public class GeneralExample {
         R<ManualCompactionResponse> response = milvusClient.manualCompact(ManualCompactParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         return response;
     }
 
     private R<MutationResult> insertColumns(String partitionName, int count) {
         System.out.println("========== insertColumns() ==========");
-        List<List<Float>> vectors = generateFloatVectors(count);
+        List<List<Float>> vectors = CommonUtils.generateFloatVectors(VECTOR_DIM, count);
 
         Random ran = new Random();
         List<Integer> ages = new ArrayList<>();
@@ -414,7 +402,7 @@ public class GeneralExample {
                 .build();
 
         R<MutationResult> response = milvusClient.insert(insertParam);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         return response;
     }
 
@@ -426,7 +414,7 @@ public class GeneralExample {
         for (long i = 0L; i < count; ++i) {
             JSONObject row = new JSONObject();
             row.put(AGE_FIELD, ran.nextInt(99));
-            row.put(VECTOR_FIELD, generateFloatVector());
+            row.put(VECTOR_FIELD, CommonUtils.generateFloatVector(VECTOR_DIM));
 
             rowsData.add(row);
         }
@@ -438,33 +426,10 @@ public class GeneralExample {
                 .build();
 
         R<MutationResult> response = milvusClient.insert(insertParam);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         return response;
     }
 
-    private List<List<Float>> generateFloatVectors(int count) {
-        Random ran = new Random();
-        List<List<Float>> vectors = new ArrayList<>();
-        for (int n = 0; n < count; ++n) {
-            List<Float> vector = new ArrayList<>();
-            for (int i = 0; i < VECTOR_DIM; ++i) {
-                vector.add(ran.nextFloat());
-            }
-            vectors.add(vector);
-        }
-
-        return vectors;
-    }
-
-    private List<Float> generateFloatVector() {
-        Random ran = new Random();
-        List<Float> vector = new ArrayList<>();
-        for (int i = 0; i < VECTOR_DIM; ++i) {
-            vector.add(ran.nextFloat());
-        }
-        return vector;
-    }
-
     public static void main(String[] args) {
         GeneralExample example = new GeneralExample();
 

+ 11 - 33
examples/main/java/io/milvus/HighLevelExample.java

@@ -17,8 +17,6 @@
  * under the License.
  */
 
-package io.milvus;
-
 import com.alibaba.fastjson.JSONObject;
 import com.google.common.collect.Lists;
 import io.milvus.client.MilvusServiceClient;
@@ -39,12 +37,6 @@ import java.util.ArrayList;
 import java.util.List;
 import java.util.Random;
 
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
-// Note:
-// Due do a technical limitation, the Milvus 2.0 not allow to create multi-vector-fields within a collection.
-// So this example only create a single vector field in the collection, but we suppose the next version
-// should support this function.
-///////////////////////////////////////////////////////////////////////////////////////////////////////////
 
 public class HighLevelExample {
     private static final MilvusServiceClient milvusClient;
@@ -75,33 +67,19 @@ public class HighLevelExample {
     private static final String BOOL_FIELD_NAME = "bool";
     private static final String FLOAT_FIELD_NAME = "float";
     private static final String DOUBLE_FIELD_NAME = "double";
-
-    private static void handleResponseStatus(R<?> r) {
-        if (r.getStatus() != R.Status.Success.getCode()) {
-            throw new RuntimeException(r.getMessage());
-        }
-    }
+    
 
     private R<DescribeCollectionResponse> describeCollection() {
         System.out.println("========== describeCollection() ==========");
         R<DescribeCollectionResponse> response = milvusClient.describeCollection(DescribeCollectionParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         DescCollResponseWrapper wrapper = new DescCollResponseWrapper(response.getData());
         System.out.println(wrapper);
         return response;
     }
 
-    private List<Float> generateFloatVector() {
-        Random ran = new Random();
-        List<Float> vector = new ArrayList<>();
-        for (int i = 0; i < VECTOR_DIM; ++i) {
-            vector.add(ran.nextFloat());
-        }
-        return vector;
-    }
-
     // >>>>>>>>>>>>> high level api
     private R<RpcStatus> createCollection() {
         System.out.println("========== high level createCollection ==========");
@@ -114,7 +92,7 @@ public class HighLevelExample {
                 .build();
 
         R<RpcStatus> response = milvusClient.createCollection(createSimpleCollectionParam);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(JacksonUtils.toJsonString(response.getData()));
         return response;
     }
@@ -125,7 +103,7 @@ public class HighLevelExample {
                 .build();
 
         R<ListCollectionsResponse> response = milvusClient.listCollections(listCollectionsParam);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -137,7 +115,7 @@ public class HighLevelExample {
         for (long i = 0L; i < rowCount; ++i) {
             JSONObject row = new JSONObject();
             row.put(AGE_FIELD, ran.nextInt(99));
-            row.put(VECTOR_FIELD, generateFloatVector());
+            row.put(VECTOR_FIELD, CommonUtils.generateFloatVector(VECTOR_DIM));
 
             // $meta if collection EnableDynamicField, you can input this field not exist in schema, else deny
             row.put(INT32_FIELD_NAME, ran.nextInt());
@@ -166,7 +144,7 @@ public class HighLevelExample {
                 .build();
 
         R<InsertResponse> response = milvusClient.insert(insertRowsParam);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println("insertCount: " + response.getData().getInsertCount());
         System.out.println("insertIds: " + response.getData().getInsertIds());
         return response;
@@ -180,7 +158,7 @@ public class HighLevelExample {
                 .build();
 
         R<DeleteResponse> response = milvusClient.delete(deleteIdsParam);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         System.out.println(response);
         return response;
     }
@@ -193,7 +171,7 @@ public class HighLevelExample {
                 .build();
 
         R<GetResponse> response = milvusClient.get(getParam);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         for (QueryResultsWrapper.RowRecord rowRecord : response.getData().getRowRecords()) {
             System.out.println(rowRecord);
         }
@@ -204,7 +182,7 @@ public class HighLevelExample {
         System.out.println("========== high level search ==========");
         SearchSimpleParam searchSimpleParam = SearchSimpleParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
-                .withVectors(generateFloatVector())
+                .withVectors(CommonUtils.generateFloatVector(VECTOR_DIM))
                 .withFilter(filter)
                 .withLimit(100L)
                 .withOffset(0L)
@@ -213,7 +191,7 @@ public class HighLevelExample {
                 .build();
 
         R<SearchResponse> response = milvusClient.search(searchSimpleParam);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         for (QueryResultsWrapper.RowRecord rowRecord : response.getData().getRowRecords(0)) {
             System.out.println(rowRecord);
         }
@@ -234,7 +212,7 @@ public class HighLevelExample {
                 .build();
 
         R<QueryResponse> response = milvusClient.query(querySimpleParam);
-        handleResponseStatus(response);
+        CommonUtils.handleResponseStatus(response);
         for (QueryResultsWrapper.RowRecord rowRecord : response.getData().getRowRecords()) {
             System.out.println(rowRecord);
         }

+ 314 - 0
examples/main/java/io/milvus/HybridSearchExample.java

@@ -0,0 +1,314 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
+import io.milvus.client.MilvusServiceClient;
+import io.milvus.common.clientenum.ConsistencyLevelEnum;
+import io.milvus.grpc.DataType;
+import io.milvus.grpc.GetCollectionStatisticsResponse;
+import io.milvus.grpc.MutationResult;
+import io.milvus.grpc.SearchResults;
+import io.milvus.param.*;
+import io.milvus.param.collection.*;
+import io.milvus.param.dml.*;
+import io.milvus.param.dml.ranker.*;
+import io.milvus.param.index.CreateIndexParam;
+import io.milvus.response.GetCollStatResponseWrapper;
+import io.milvus.response.SearchResultsWrapper;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+public class HybridSearchExample {
+    private static final String HOST = "localhost";
+    private static final int HOST_PORT = 19530;
+    private static final String COLLECTION_NAME = "java_sdk_example_hybrid_search";
+    private static final String ID_FIELD = "ID";
+
+    private static final String FLOAT_VECTOR_FIELD = "float_vector";
+    private static final Integer FLOAT_VECTOR_DIM = 128;
+    private static final MetricType FLOAT_VECTOR_METRIC = MetricType.COSINE;
+
+    private static final String BINARY_VECTOR_FIELD = "binary_vector";
+    private static final Integer BINARY_VECTOR_DIM = 256;
+    private static final MetricType BINARY_VECTOR_METRIC = MetricType.JACCARD;
+
+    private static final String FLOAT16_VECTOR_FIELD = "float16_vector";
+    private static final Integer FLOAT16_VECTOR_DIM = 256;
+    private static final MetricType FLOAT16_VECTOR_METRIC = MetricType.L2;
+
+    private static final String SPARSE_VECTOR_FIELD = "sparse_vector";
+    private static final MetricType SPARSE_VECTOR_METRIC = MetricType.IP;
+
+    private static void createCollection() {
+        MilvusServiceClient milvusClient = new MilvusServiceClient(ConnectParam.newBuilder()
+                .withHost(HOST)
+                .withPort(HOST_PORT)
+                .build());
+
+        // Define fields
+        // There is a configuration in milvus.yaml to define the max vector fields in a collection
+        // proxy.maxVectorFieldNum: 4
+        // By default, the max vector fields number is 4
+        // In v2.4.0 there is a known bug that sparse vectors and float16 vectors in one collection
+        // will crash milvus, so we comment out float16 vector field here.
+        // https://github.com/milvus-io/milvus/issues/31988
+        List<FieldType> fieldsSchema = Arrays.asList(
+                FieldType.newBuilder()
+                        .withName(ID_FIELD)
+                        .withDataType(DataType.Int64)
+                        .withPrimaryKey(true)
+                        .withAutoID(false)
+                        .build(),
+                FieldType.newBuilder()
+                        .withName(FLOAT_VECTOR_FIELD)
+                        .withDataType(DataType.FloatVector)
+                        .withDimension(FLOAT_VECTOR_DIM)
+                        .build(),
+                FieldType.newBuilder()
+                        .withName(BINARY_VECTOR_FIELD)
+                        .withDataType(DataType.BinaryVector)
+                        .withDimension(BINARY_VECTOR_DIM)
+                        .build(),
+//                FieldType.newBuilder()
+//                        .withName(FLOAT16_VECTOR_FIELD)
+//                        .withDataType(DataType.Float16Vector)
+//                        .withDimension(FLOAT16_VECTOR_DIM)
+//                        .build(),
+                FieldType.newBuilder()
+                        .withName(SPARSE_VECTOR_FIELD)
+                        .withDataType(DataType.SparseFloatVector)
+                        .build()
+        );
+
+        // Create the collection with multi vector fields
+        R<RpcStatus> resp = milvusClient.createCollection(CreateCollectionParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withSchema(CollectionSchemaParam.newBuilder().withFieldTypes(fieldsSchema).build())
+                .build());
+        CommonUtils.handleResponseStatus(resp);
+
+        // Specify an index types on the vector fields.
+        resp = milvusClient.createIndex(CreateIndexParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withFieldName(FLOAT_VECTOR_FIELD)
+                .withIndexType(IndexType.IVF_PQ)
+                .withExtraParam("{\"nlist\":128, \"m\":16, \"nbits\":8}")
+                .withMetricType(FLOAT_VECTOR_METRIC)
+                .build());
+        CommonUtils.handleResponseStatus(resp);
+
+        resp = milvusClient.createIndex(CreateIndexParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withFieldName(BINARY_VECTOR_FIELD)
+                .withIndexType(IndexType.BIN_FLAT)
+                .withMetricType(BINARY_VECTOR_METRIC)
+                .build());
+        CommonUtils.handleResponseStatus(resp);
+
+//        resp = milvusClient.createIndex(CreateIndexParam.newBuilder()
+//                .withCollectionName(COLLECTION_NAME)
+//                .withFieldName(FLOAT16_VECTOR_FIELD)
+//                .withIndexType(IndexType.IVF_FLAT)
+//                .withExtraParam("{\"nlist\":128}")
+//                .withMetricType(FLOAT16_VECTOR_METRIC)
+//                .build());
+//        CommonUtils.handleResponseStatus(resp);
+
+        resp = milvusClient.createIndex(CreateIndexParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withFieldName(SPARSE_VECTOR_FIELD)
+                .withIndexType(IndexType.SPARSE_INVERTED_INDEX)
+                .withExtraParam("{\"drop_ratio_build\":0.2}")
+                .withMetricType(SPARSE_VECTOR_METRIC)
+                .build());
+        CommonUtils.handleResponseStatus(resp);
+
+        // Call loadCollection() to enable automatically loading data into memory for searching
+        milvusClient.loadCollection(LoadCollectionParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .build());
+
+        System.out.println("Collection created");
+
+        milvusClient.close();
+    }
+
+    private static void insertData() {
+        MilvusServiceClient milvusClient = new MilvusServiceClient(ConnectParam.newBuilder()
+                .withHost(HOST)
+                .withPort(HOST_PORT)
+                .build());
+
+        long idCount = 0;
+        int rowCount = 10000;
+        // Insert entities by rows
+        List<JSONObject> rows = new ArrayList<>();
+        for (long i = 1L; i <= rowCount; ++i) {
+            JSONObject row = new JSONObject();
+            row.put(ID_FIELD, idCount++);
+            row.put(FLOAT_VECTOR_FIELD, CommonUtils.generateFloatVector(FLOAT_VECTOR_DIM));
+            row.put(BINARY_VECTOR_FIELD, CommonUtils.generateBinaryVector(BINARY_VECTOR_DIM));
+//            row.put(FLOAT16_VECTOR_FIELD, CommonUtils.generateFloat16Vector(FLOAT16_VECTOR_DIM, false));
+            row.put(SPARSE_VECTOR_FIELD, CommonUtils.generateSparseVector());
+            rows.add(row);
+        }
+
+        R<MutationResult> resp = milvusClient.insert(InsertParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withRows(rows)
+                .build());
+        CommonUtils.handleResponseStatus(resp);
+
+        System.out.printf("%d entities inserted by rows", rowCount);
+
+        // Insert entities by columns
+        List<Long> ids = new ArrayList<>();
+        for (long i = 1L; i <= 10000; ++i) {
+            ids.add(idCount++);
+        }
+
+        List<InsertParam.Field> fieldsInsert = new ArrayList<>();
+        fieldsInsert.add(new InsertParam.Field(ID_FIELD, ids));
+        fieldsInsert.add(new InsertParam.Field(FLOAT_VECTOR_FIELD,
+                CommonUtils.generateFloatVectors(FLOAT_VECTOR_DIM, rowCount)));
+        fieldsInsert.add(new InsertParam.Field(BINARY_VECTOR_FIELD,
+                CommonUtils.generateBinaryVectors(BINARY_VECTOR_DIM, rowCount)));
+//        fieldsInsert.add(new InsertParam.Field(FLOAT16_VECTOR_FIELD,
+//                CommonUtils.generateFloat16Vectors(FLOAT16_VECTOR_DIM, rowCount, false)));
+        fieldsInsert.add(new InsertParam.Field(SPARSE_VECTOR_FIELD,
+                CommonUtils.generateSparseVectors(rowCount)));
+
+        resp = milvusClient.insert(InsertParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withFields(fieldsInsert)
+                .build());
+        CommonUtils.handleResponseStatus(resp);
+
+        System.out.printf("%d entities inserted by columns", rowCount);
+
+        milvusClient.close();
+    }
+
+    private static void hybridSearch() {
+        MilvusServiceClient milvusClient = new MilvusServiceClient(ConnectParam.newBuilder()
+                .withHost(HOST)
+                .withPort(HOST_PORT)
+                .build());
+
+        // Get the row count
+        R<GetCollectionStatisticsResponse> resp = milvusClient.getCollectionStatistics(GetCollectionStatisticsParam
+                .newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withFlush(true)
+                .build());
+        CommonUtils.handleResponseStatus(resp);
+
+        GetCollStatResponseWrapper stat = new GetCollStatResponseWrapper(resp.getData());
+        System.out.println("Collection row count: " + stat.getRowCount());
+
+        // Search on multiple vector fields
+        // Note that only allow one vector for each sub request
+        AnnSearchParam req1 = AnnSearchParam.newBuilder()
+                .withVectorFieldName(FLOAT_VECTOR_FIELD)
+                .withVectors(CommonUtils.generateFloatVectors(FLOAT_VECTOR_DIM, 1))
+                .withMetricType(FLOAT_VECTOR_METRIC)
+                .withParams("{\"nprobe\": 32}")
+                .withTopK(10)
+                .build();
+
+        AnnSearchParam req2 = AnnSearchParam.newBuilder()
+                .withVectorFieldName(BINARY_VECTOR_FIELD)
+                .withVectors(CommonUtils.generateBinaryVectors(BINARY_VECTOR_DIM, 1))
+                .withMetricType(BINARY_VECTOR_METRIC)
+                .withTopK(15)
+                .build();
+
+//        AnnSearchParam req3 = AnnSearchParam.newBuilder()
+//                .withVectorFieldName(FLOAT16_VECTOR_FIELD)
+//                .withVectors(CommonUtils.generateFloat16Vectors(FLOAT16_VECTOR_DIM, 1, false))
+//                .withMetricType(FLOAT16_VECTOR_METRIC)
+//                .withParams("{\"es\":200}")
+//                .withTopK(20)
+//                .build();
+
+        AnnSearchParam req4 = AnnSearchParam.newBuilder()
+                .withVectorFieldName(SPARSE_VECTOR_FIELD)
+                .withVectors(CommonUtils.generateSparseVectors(1))
+                .withMetricType(SPARSE_VECTOR_METRIC)
+                .withParams("{\"drop_ratio_search\":0.2}")
+                .withTopK(20)
+                .build();
+
+        HybridSearchParam searchParam = HybridSearchParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .addOutField(FLOAT_VECTOR_FIELD)
+                .addOutField(BINARY_VECTOR_FIELD)
+//                .addOutField(FLOAT16_VECTOR_FIELD)
+                .addOutField(SPARSE_VECTOR_FIELD)
+                .addSearchRequest(req1)
+                .addSearchRequest(req2)
+//                .addSearchRequest(req3)
+                .addSearchRequest(req4)
+                .withTopK(5)
+                .withConsistencyLevel(ConsistencyLevelEnum.STRONG)
+                .withRanker(RRFRanker.newBuilder()
+                        .withK(2)
+                        .build())
+                .build();
+
+        R<SearchResults> searchR = milvusClient.hybridSearch(searchParam);
+        CommonUtils.handleResponseStatus(searchR);
+
+        // Print search result
+        SearchResultsWrapper results = new SearchResultsWrapper(searchR.getData().getResults());
+        List<SearchResultsWrapper.IDScore> scores = results.getIDScore(0);
+        for (int i = 0; i < scores.size(); ++i) {
+            System.out.println(scores.get(i));
+        }
+
+
+        milvusClient.close();
+    }
+
+    private static void dropCollection() {
+        MilvusServiceClient milvusClient = new MilvusServiceClient(ConnectParam.newBuilder()
+                .withHost(HOST)
+                .withPort(HOST_PORT)
+                .build());
+
+        R<RpcStatus> resp = milvusClient.dropCollection(DropCollectionParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .build());
+        CommonUtils.handleResponseStatus(resp);
+
+        System.out.println("Collection dropped");
+
+        milvusClient.close();
+    }
+
+    public static void main(String[] args) {
+        createCollection();
+        insertData();
+        hybridSearch();
+        dropCollection();
+    }
+}

+ 0 - 1
examples/main/java/io/milvus/RBACExample.java

@@ -17,7 +17,6 @@
  * under the License.
  */
 
-package io.milvus;
 
 import io.milvus.client.MilvusServiceClient;
 import io.milvus.grpc.ListCredUsersResponse;

+ 0 - 1
examples/main/java/io/milvus/SimpleExample.java

@@ -17,7 +17,6 @@
  * under the License.
  */
 
-package io.milvus;
 
 import com.alibaba.fastjson.JSONObject;
 import io.milvus.client.MilvusServiceClient;

+ 28 - 30
examples/main/java/io/milvus/SparseVectorExample.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 import io.milvus.client.MilvusServiceClient;
 import io.milvus.common.clientenum.ConsistencyLevelEnum;
 import io.milvus.grpc.*;
@@ -11,7 +30,6 @@ import io.milvus.response.FieldDataWrapper;
 import io.milvus.response.QueryResultsWrapper;
 import io.milvus.response.SearchResultsWrapper;
 
-import java.nio.ByteBuffer;
 import java.util.*;
 
 public class SparseVectorExample {
@@ -19,26 +37,6 @@ public class SparseVectorExample {
     private static final String ID_FIELD = "id";
     private static final String VECTOR_FIELD = "vector";
 
-    private static List<SortedMap<Long, Float>> generateVectors(int count) {
-        Random ran = new Random();
-        List<SortedMap<Long, Float>> vectors = new ArrayList<>();
-        for (int n = 0; n < count; ++n) {
-            SortedMap<Long, Float> sparse = new TreeMap<>();
-            int dim = ran.nextInt(10) + 1;
-            for (int i = 0; i < dim; ++i) {
-                sparse.put((long)ran.nextInt(1000000), ran.nextFloat());
-            }
-            vectors.add(sparse);
-        }
-        return vectors;
-
-    }
-
-    private static void handleResponseStatus(R<?> r) {
-        if (r.getStatus() != R.Status.Success.getCode()) {
-            throw new RuntimeException(r.getMessage());
-        }
-    }
 
     public static void main(String[] args) {
         // Connect to Milvus server. Replace the "localhost" and port with your Milvus server address.
@@ -51,7 +49,7 @@ public class SparseVectorExample {
         R<Boolean> hasR = milvusClient.hasCollection(HasCollectionParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(hasR);
+        CommonUtils.handleResponseStatus(hasR);
         if (hasR.getData()) {
             milvusClient.dropCollection(DropCollectionParam.newBuilder()
                     .withCollectionName(COLLECTION_NAME)
@@ -78,7 +76,7 @@ public class SparseVectorExample {
                 .withConsistencyLevel(ConsistencyLevelEnum.STRONG)
                 .withFieldTypes(fieldsSchema)
                 .build());
-        handleResponseStatus(ret);
+        CommonUtils.handleResponseStatus(ret);
         System.out.println("Collection created");
 
         // Insert entities
@@ -87,7 +85,7 @@ public class SparseVectorExample {
         for (long i = 0L; i < rowCount; ++i) {
             ids.add(i);
         }
-        List<SortedMap<Long, Float>> vectors = generateVectors(rowCount);
+        List<SortedMap<Long, Float>> vectors = CommonUtils.generateSparseVectors(rowCount);
 
         List<InsertParam.Field> fieldsInsert = new ArrayList<>();
         fieldsInsert.add(new InsertParam.Field(ID_FIELD, ids));
@@ -99,14 +97,14 @@ public class SparseVectorExample {
                 .build();
 
         R<MutationResult> insertR = milvusClient.insert(insertParam);
-        handleResponseStatus(insertR);
+        CommonUtils.handleResponseStatus(insertR);
 
         // Flush the data to storage for testing purpose
         // Note that no need to manually call flush interface in practice
         R<FlushResponse> flushR = milvusClient.flush(FlushParam.newBuilder().
                 addCollectionName(COLLECTION_NAME).
                 build());
-        handleResponseStatus(flushR);
+        CommonUtils.handleResponseStatus(flushR);
         System.out.println("Entities inserted");
 
         // Specify an index type on the vector field.
@@ -117,14 +115,14 @@ public class SparseVectorExample {
                 .withMetricType(MetricType.IP)
                 .withExtraParam("{\"drop_ratio_build\":0.2}")
                 .build());
-        handleResponseStatus(ret);
+        CommonUtils.handleResponseStatus(ret);
         System.out.println("Index created");
 
         // Call loadCollection() to enable automatically loading data into memory for searching
         ret = milvusClient.loadCollection(LoadCollectionParam.newBuilder()
                 .withCollectionName(COLLECTION_NAME)
                 .build());
-        handleResponseStatus(ret);
+        CommonUtils.handleResponseStatus(ret);
         System.out.println("Collection loaded");
 
         // Pick some vectors from the inserted vectors to search
@@ -142,7 +140,7 @@ public class SparseVectorExample {
                     .addOutField(VECTOR_FIELD)
                     .withParams("{\"drop_ratio_search\":0.2}")
                     .build());
-            handleResponseStatus(searchRet);
+            CommonUtils.handleResponseStatus(searchRet);
 
             // The search() allows multiple target vectors to search in a batch.
             // Here we only input one vector to search, get the result of No.0 vector to check
@@ -166,7 +164,7 @@ public class SparseVectorExample {
                 .withExpr(String.format("id == %d", n))
                 .addOutField(VECTOR_FIELD)
                 .build());
-        handleResponseStatus(queryR);
+        CommonUtils.handleResponseStatus(queryR);
         QueryResultsWrapper queryWrapper = new QueryResultsWrapper(queryR.getData());
         FieldDataWrapper field = queryWrapper.getFieldWrapper(VECTOR_FIELD);
         List<?> r = field.getFieldData();

+ 3 - 10
examples/main/java/io/milvus/TLSExample.java

@@ -17,17 +17,10 @@
  * under the License.
  */
 
-package io.milvus;
-
-import com.alibaba.fastjson.JSONObject;
 import io.milvus.client.MilvusServiceClient;
-import io.milvus.grpc.*;
-import io.milvus.param.*;
-import io.milvus.param.collection.*;
-import io.milvus.param.dml.*;
-import io.milvus.param.index.*;
-import io.milvus.response.*;
-import java.util.*;
+import io.milvus.grpc.CheckHealthResponse;
+import io.milvus.param.ConnectParam;
+import io.milvus.param.R;
 
 
 // Note: read the following description before running this example

+ 19 - 0
src/main/java/io/milvus/bulkwriter/Buffer.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter;
 
 import com.alibaba.fastjson.JSONObject;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/BulkWriter.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter;
 
 import com.alibaba.fastjson.JSONObject;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/CloudImport.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter;
 
 import com.google.gson.Gson;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/LocalBulkWriter.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter;
 
 import com.alibaba.fastjson.JSONObject;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/RemoteBulkWriter.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter;
 
 import com.alibaba.fastjson.JSONObject;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/common/clientenum/BulkFileType.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.common.clientenum;
 
 public enum BulkFileType {

+ 19 - 0
src/main/java/io/milvus/bulkwriter/common/clientenum/CloudStorage.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.common.clientenum;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/common/clientenum/TypeSize.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.common.clientenum;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/common/utils/GeneratorUtils.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.common.utils;
 
 import org.apache.commons.lang3.RandomUtils;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/common/utils/ImportUtils.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.common.utils;
 
 import java.util.Collection;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/common/utils/ParquetReaderUtils.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.common.utils;
 
 import org.apache.avro.generic.GenericData;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/common/utils/ParquetUtils.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.common.utils;
 
 import io.milvus.param.collection.CollectionSchemaParam;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/connect/AzureConnectParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.connect;
 
 import com.azure.core.credential.TokenCredential;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/connect/S3ConnectParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.connect;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/connect/StorageConnectParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.connect;
 
 public class StorageConnectParam {

+ 19 - 0
src/main/java/io/milvus/bulkwriter/response/BulkImportResponse.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.response;
 
 import lombok.AllArgsConstructor;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/response/GetImportProgressResponse.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.response;
 
 import lombok.AllArgsConstructor;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/response/ListImportJobsResponse.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.response;
 
 import lombok.AllArgsConstructor;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/response/RestfulResponse.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.response;
 
 import lombok.AllArgsConstructor;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/storage/StorageClient.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.storage;
 
 

+ 19 - 0
src/main/java/io/milvus/bulkwriter/storage/client/AzureStorageClient.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.storage.client;
 
 import com.azure.core.credential.TokenCredential;

+ 19 - 0
src/main/java/io/milvus/bulkwriter/storage/client/MinioStorageClient.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.bulkwriter.storage.client;
 
 import com.google.common.collect.HashMultimap;

+ 68 - 0
src/main/java/io/milvus/client/AbstractMilvusGrpcClient.java

@@ -1693,6 +1693,74 @@ public abstract class AbstractMilvusGrpcClient implements MilvusClient {
         return Futures.transform(response, transformFunc::apply, MoreExecutors.directExecutor());
     }
 
+    @Override
+    public R<SearchResults> hybridSearch(HybridSearchParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+
+        logDebug(requestParam.toString());
+        String title = String.format("HybridSearchRequest collectionName:%s", requestParam.getCollectionName());
+
+        try {
+            HybridSearchRequest searchRequest = ParamUtils.convertHybridSearchParam(requestParam);
+            SearchResults response = this.blockingStub().hybridSearch(searchRequest);
+            handleResponse(title, response.getStatus());
+            return R.success(response);
+        } catch (StatusRuntimeException e) {
+            logError("{} RPC failed! Exception:{}", title, e);
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("{} failed! Exception:{}", title, e);
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public ListenableFuture<R<SearchResults>> hybridSearchAsync(HybridSearchParam requestParam) {
+        if (!clientIsReady()) {
+            return Futures.immediateFuture(
+                    R.failed(new ClientNotConnectedException("Client rpc channel is not ready")));
+        }
+
+        logDebug(requestParam.toString());
+        String title = String.format("HybridSearchAsyncRequest collectionName:%s", requestParam.getCollectionName());
+
+        HybridSearchRequest searchRequest = ParamUtils.convertHybridSearchParam(requestParam);
+        ListenableFuture<SearchResults> response = this.futureStub().hybridSearch(searchRequest);
+
+        Futures.addCallback(
+                response,
+                new FutureCallback<SearchResults>() {
+                    @Override
+                    public void onSuccess(SearchResults result) {
+                        if (result.getStatus().getErrorCode() == ErrorCode.Success) {
+                            logDebug("{} successfully!", title);
+                        } else {
+                            logError("{} failed:\n{}", title, result.getStatus().getReason());
+                        }
+                    }
+
+                    @Override
+                    public void onFailure(@Nonnull Throwable t) {
+                        logError("{} failed:\n{}", title, t.getMessage());
+                    }
+                },
+                MoreExecutors.directExecutor());
+
+        Function<SearchResults, R<SearchResults>> transformFunc =
+                results -> {
+                    Status status = results.getStatus();
+                    if (status.getCode() != 0 || status.getErrorCode() != ErrorCode.Success) {
+                        return R.failed(new ServerException(status.getReason(), status.getCode(), status.getErrorCode()));
+                    } else {
+                        return R.success(results);
+                    }
+                };
+
+        return Futures.transform(response, transformFunc::apply, MoreExecutors.directExecutor());
+    }
+
     @Override
     public R<QueryResults> query(@NonNull QueryParam requestParam) {
         if (!clientIsReady()) {

+ 16 - 0
src/main/java/io/milvus/client/MilvusClient.java

@@ -425,6 +425,22 @@ public interface MilvusClient {
      */
     ListenableFuture<R<SearchResults>> searchAsync(SearchParam requestParam);
 
+    /**
+     * Conducts multi vector similarity search with a ranker for rearrangement.
+     *
+     * @param requestParam {@link HybridSearchParam}
+     * @return {status:result code, data: SearchResults{topK results}}
+     */
+    R<SearchResults> hybridSearch(HybridSearchParam requestParam);
+
+    /**
+     * Conducts multi vector similarity search asynchronously with a ranker for rearrangement.
+     *
+     * @param requestParam {@link HybridSearchParam}
+     * @return a <code>ListenableFuture</code> object which holds the object {status:result code, data: SearchResults{topK results}}
+     */
+    ListenableFuture<R<SearchResults>> hybridSearchAsync(HybridSearchParam requestParam);
+
     /**
      * Queries entity(s) based on scalar field(s) filtered by boolean expression.
      * Note that the order of the returned entities cannot be guaranteed.

+ 10 - 0
src/main/java/io/milvus/client/MilvusMultiServiceClient.java

@@ -420,6 +420,16 @@ public class MilvusMultiServiceClient implements MilvusClient {
         return this.clusterFactory.getMaster().getClient().searchAsync(requestParam);
     }
 
+    @Override
+    public R<SearchResults> hybridSearch(HybridSearchParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().hybridSearch(requestParam);
+    }
+
+    @Override
+    public ListenableFuture<R<SearchResults>> hybridSearchAsync(HybridSearchParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().hybridSearchAsync(requestParam);
+    }
+
     @Override
     public R<QueryResults> query(QueryParam requestParam) {
         return this.clusterFactory.getMaster().getClient().query(requestParam);

+ 5 - 0
src/main/java/io/milvus/client/MilvusServiceClient.java

@@ -528,6 +528,11 @@ public class MilvusServiceClient extends AbstractMilvusGrpcClient {
         return retry(()-> super.search(requestParam));
     }
 
+    @Override
+    public R<SearchResults> hybridSearch(HybridSearchParam requestParam) {
+        return retry(()-> super.hybridSearch(requestParam));
+    }
+
     @Override
     public R<QueryResults> query(QueryParam requestParam) {
         return retry(()-> super.query(requestParam));

+ 19 - 0
src/main/java/io/milvus/common/clientenum/ConsistencyLevelEnum.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.common.clientenum;
 
 import lombok.Getter;

+ 19 - 0
src/main/java/io/milvus/common/constant/MilvusClientConstant.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.common.constant;
 
 public class MilvusClientConstant {

+ 19 - 0
src/main/java/io/milvus/common/utils/ExceptionUtils.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.common.utils;
 
 import io.milvus.exception.UnExpectedException;

+ 19 - 0
src/main/java/io/milvus/common/utils/JacksonUtils.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.common.utils;
 
 import com.fasterxml.jackson.core.type.TypeReference;

+ 19 - 0
src/main/java/io/milvus/common/utils/URLParser.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.utils;
 
 import lombok.Getter;

+ 19 - 0
src/main/java/io/milvus/common/utils/VectorUtils.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.common.utils;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/connection/ClusterFactory.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.connection;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/connection/ClusterListener.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.connection;
 
 import okhttp3.OkHttpClient;

+ 19 - 0
src/main/java/io/milvus/connection/Listener.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.connection;
 
 /**

+ 19 - 0
src/main/java/io/milvus/connection/QueryNodeListener.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.connection;
 
 import io.milvus.common.clientenum.ConsistencyLevelEnum;

+ 19 - 0
src/main/java/io/milvus/connection/ServerMonitor.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.connection;
 
 import io.milvus.param.QueryNodeSingleSearch;

+ 19 - 0
src/main/java/io/milvus/connection/ServerSetting.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.connection;
 
 import io.milvus.client.MilvusClient;

+ 19 - 0
src/main/java/io/milvus/param/LogLevel.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param;
 
 public enum LogLevel {

+ 19 - 0
src/main/java/io/milvus/param/MultiConnectParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param;
 
 import com.google.common.collect.Lists;

+ 128 - 19
src/main/java/io/milvus/param/ParamUtils.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param;
 
 import com.alibaba.fastjson.JSONObject;
@@ -9,10 +28,8 @@ import io.milvus.exception.IllegalResponseException;
 import io.milvus.exception.ParamException;
 import io.milvus.grpc.*;
 import io.milvus.param.collection.FieldType;
-import io.milvus.param.dml.InsertParam;
-import io.milvus.param.dml.QueryParam;
-import io.milvus.param.dml.SearchParam;
-import io.milvus.param.dml.UpsertParam;
+import io.milvus.param.dml.*;
+import io.milvus.param.dml.ranker.BaseRanker;
 import io.milvus.response.DescCollResponseWrapper;
 import lombok.Builder;
 import lombok.Getter;
@@ -445,21 +462,8 @@ public class ParamUtils {
     }
 
     @SuppressWarnings("unchecked")
-    public static SearchRequest convertSearchParam(@NonNull SearchParam requestParam) throws ParamException {
-        SearchRequest.Builder builder = SearchRequest.newBuilder()
-                .setCollectionName(requestParam.getCollectionName());
-
-        if (!requestParam.getPartitionNames().isEmpty()) {
-            requestParam.getPartitionNames().forEach(builder::addPartitionNames);
-        }
-        if (StringUtils.isNotEmpty(requestParam.getDatabaseName())) {
-            builder.setDbName(requestParam.getDatabaseName());
-        }
-
-        // prepare target vectors
-        // TODO: check target vector dimension(use DescribeCollection get schema to compare)
+    private static ByteString convertPlaceholder(List<?> vectors) throws ParamException {
         PlaceholderType plType = PlaceholderType.None;
-        List<?> vectors = requestParam.getVectors();
         List<ByteString> byteStrings = new ArrayList<>();
         for (Object vector : vectors) {
             if (vector instanceof List) {
@@ -502,7 +506,23 @@ public class ParamUtils {
                 .addPlaceholders(plv)
                 .build();
 
-        ByteString byteStr = placeholderGroup.toByteString();
+        return placeholderGroup.toByteString();
+    }
+
+    @SuppressWarnings("unchecked")
+    public static SearchRequest convertSearchParam(@NonNull SearchParam requestParam) throws ParamException {
+        SearchRequest.Builder builder = SearchRequest.newBuilder()
+                .setCollectionName(requestParam.getCollectionName());
+
+        if (!requestParam.getPartitionNames().isEmpty()) {
+            requestParam.getPartitionNames().forEach(builder::addPartitionNames);
+        }
+        if (StringUtils.isNotEmpty(requestParam.getDatabaseName())) {
+            builder.setDbName(requestParam.getDatabaseName());
+        }
+
+        // prepare target vectors
+        ByteString byteStr = convertPlaceholder(requestParam.getVectors());
         builder.setPlaceholderGroup(byteStr);
         builder.setNq(requestParam.getNQ());
 
@@ -588,6 +608,95 @@ public class ParamUtils {
         return builder.build();
     }
 
+    public static SearchRequest convertAnnSearchParam(@NonNull AnnSearchParam annSearchParam,
+                                                      ConsistencyLevelEnum consistencyLevel) {
+        SearchRequest.Builder builder = SearchRequest.newBuilder();
+        ByteString byteStr = convertPlaceholder(annSearchParam.getVectors());
+        builder.setPlaceholderGroup(byteStr);
+        builder.setNq(annSearchParam.getNQ());
+
+        builder.addSearchParams(
+                        KeyValuePair.newBuilder()
+                                .setKey(Constant.VECTOR_FIELD)
+                                .setValue(annSearchParam.getVectorFieldName())
+                                .build())
+                .addSearchParams(
+                        KeyValuePair.newBuilder()
+                                .setKey(Constant.TOP_K)
+                                .setValue(String.valueOf(annSearchParam.getTopK()))
+                                .build());
+
+        if (!Objects.equals(annSearchParam.getMetricType(), MetricType.None.name())) {
+            builder.addSearchParams(
+                    KeyValuePair.newBuilder()
+                            .setKey(Constant.METRIC_TYPE)
+                            .setValue(annSearchParam.getMetricType())
+                            .build());
+        }
+
+        if (null != annSearchParam.getParams() && !annSearchParam.getParams().isEmpty()) {
+            builder.addSearchParams(
+                    KeyValuePair.newBuilder()
+                            .setKey(Constant.PARAMS)
+                            .setValue(annSearchParam.getParams())
+                            .build());
+        }
+
+        // always use expression since dsl is discarded
+        builder.setDslType(DslType.BoolExprV1);
+        if (annSearchParam.getExpr() != null && !annSearchParam.getExpr().isEmpty()) {
+            builder.setDsl(annSearchParam.getExpr());
+        }
+
+        if (consistencyLevel == null) {
+            builder.setUseDefaultConsistency(true);
+        } else {
+            builder.setConsistencyLevelValue(consistencyLevel.getCode());
+        }
+
+        return builder.build();
+    }
+
+    public static HybridSearchRequest convertHybridSearchParam(@NonNull HybridSearchParam requestParam) throws ParamException {
+        HybridSearchRequest.Builder builder = HybridSearchRequest.newBuilder()
+                .setCollectionName(requestParam.getCollectionName());
+
+        if (!requestParam.getPartitionNames().isEmpty()) {
+            requestParam.getPartitionNames().forEach(builder::addPartitionNames);
+        }
+        if (StringUtils.isNotEmpty(requestParam.getDatabaseName())) {
+            builder.setDbName(requestParam.getDatabaseName());
+        }
+
+        for (AnnSearchParam req : requestParam.getSearchRequests()) {
+            SearchRequest searchRequest = ParamUtils.convertAnnSearchParam(req, requestParam.getConsistencyLevel());
+            builder.addRequests(searchRequest);
+        }
+
+        // set ranker
+        BaseRanker ranker = requestParam.getRanker();
+        Map<String, String> props = ranker.getProperties();
+        props.put("limit", String.format("%d", requestParam.getTopK()));
+        props.put("round_decimal", String.format("%d", requestParam.getRoundDecimal()));
+        List<KeyValuePair> propertiesList = ParamUtils.AssembleKvPair(props);
+        if (CollectionUtils.isNotEmpty(propertiesList)) {
+            propertiesList.forEach(builder::addRankParams);
+        }
+
+        // output fields
+        if (!requestParam.getOutFields().isEmpty()) {
+            requestParam.getOutFields().forEach(builder::addOutputFields);
+        }
+
+        if (requestParam.getConsistencyLevel() == null) {
+            builder.setUseDefaultConsistency(true);
+        } else {
+            builder.setConsistencyLevelValue(requestParam.getConsistencyLevel().getCode());
+        }
+
+        return builder.build();
+    }
+
     public static QueryRequest convertQueryParam(@NonNull QueryParam requestParam) {
         long guaranteeTimestamp = getGuaranteeTimestamp(requestParam.getConsistencyLevel(),
                 requestParam.getGuaranteeTimestamp(), requestParam.getGracefulTime());

+ 19 - 0
src/main/java/io/milvus/param/QueryNodeSingleSearch.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/ServerAddress.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/alias/AlterAliasParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.alias;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/alias/CreateAliasParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.alias;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/alias/DropAliasParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.alias;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/alias/ListAliasesParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.alias;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/collection/FlushParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.collection;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/control/GetCompactionPlansParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.control;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/control/GetCompactionStateParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.control;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/control/GetFlushAllStateParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.control;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/control/GetFlushStateParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.control;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/control/GetReplicasParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.control;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/control/ManualCompactParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.control;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/credential/CreateCredentialParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.credential;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/credential/DeleteCredentialParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.credential;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/credential/ListCredUsersParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.credential;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/credential/UpdateCredentialParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.credential;
 
 import io.milvus.exception.ParamException;

+ 219 - 0
src/main/java/io/milvus/param/dml/AnnSearchParam.java

@@ -0,0 +1,219 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package io.milvus.param.dml;
+
+import io.milvus.exception.ParamException;
+import io.milvus.param.MetricType;
+import io.milvus.param.ParamUtils;
+
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.SortedMap;
+
+/**
+ * Parameters for <code>hybridSearch</code> interface.
+ */
+@Getter
+@ToString
+public class AnnSearchParam {
+
+    private final String metricType;
+    private final String vectorFieldName;
+    private final int topK;
+    private final String expr;
+    private final List<?> vectors;
+    private final Long NQ;
+    private final String params;
+
+    private AnnSearchParam(@NonNull Builder builder) {
+        this.metricType = builder.metricType.name();
+        this.vectorFieldName = builder.vectorFieldName;
+        this.topK = builder.topK;
+        this.expr = builder.expr;
+        this.vectors = builder.vectors;
+        this.NQ = builder.NQ;
+        this.params = builder.params;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link AnnSearchParam} class.
+     */
+    public static class Builder {
+        private MetricType metricType = MetricType.None;
+        private String vectorFieldName;
+        private Integer topK;
+        private String expr = "";
+        private List<?> vectors;
+        private Long NQ;
+        private String params = "{}";
+
+        Builder() {
+        }
+
+        /**
+         * Sets metric type of ANN searching.
+         *
+         * @param metricType metric type
+         * @return <code>Builder</code>
+         */
+        public Builder withMetricType(@NonNull MetricType metricType) {
+            this.metricType = metricType;
+            return this;
+        }
+
+        /**
+         * Sets target vector field by name. Field name cannot be empty or null.
+         *
+         * @param vectorFieldName vector field name
+         * @return <code>Builder</code>
+         */
+        public Builder withVectorFieldName(@NonNull String vectorFieldName) {
+            this.vectorFieldName = vectorFieldName;
+            return this;
+        }
+
+        /**
+         * Sets topK value of ANN search.
+         *
+         * @param topK topK value
+         * @return <code>Builder</code>
+         */
+        public Builder withTopK(@NonNull Integer topK) {
+            this.topK = topK;
+            return this;
+        }
+
+        /**
+         * Sets expression to filter out entities before searching (Optional).
+         * @see <a href="https://milvus.io/docs/v2.0.0/boolean.md">Boolean Expression Rules</a>
+         *
+         * @param expr filtering expression
+         * @return <code>Builder</code>
+         */
+        public Builder withExpr(@NonNull String expr) {
+            this.expr = expr;
+            return this;
+        }
+
+        /**
+         * Sets the target vectors.
+         * Note: currently, only support one vector for search.
+         *
+         * @param vectors list of target vectors:
+         *                if vector type is FloatVector, vectors is List of List Float;
+         *                if vector type is BinaryVector/Float16Vector/BFloat16Vector, vectors is List of ByteBuffer;
+         *                if vector type is SparseFloatVector, values is List of SortedMap[Long, Float];
+         * @return <code>Builder</code>
+         */
+        public Builder withVectors(@NonNull List<?> vectors) {
+            this.vectors = vectors;
+            this.NQ = (long) vectors.size();
+            return this;
+        }
+
+
+        /**
+         * Sets the search parameters specific to the index type.
+         *
+         * For example: IVF index, the search parameters can be "{\"nprobe\":10}"
+         * For more information: @see <a href="https://milvus.io/docs/v2.0.0/index_selection.md">Index Selection</a>
+         *
+         * @param params extra parameters in json format
+         * @return <code>Builder</code>
+         */
+        public Builder withParams(@NonNull String params) {
+            this.params = params;
+            return this;
+        }
+
+
+        /**
+         * Verifies parameters and creates a new {@link AnnSearchParam} instance.
+         *
+         * @return {@link AnnSearchParam}
+         */
+        public AnnSearchParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(vectorFieldName, "Target field name");
+
+            if (topK <= 0) {
+                throw new ParamException("TopK value is illegal");
+            }
+
+            if (vectors == null || vectors.isEmpty()) {
+                throw new ParamException("Target vectors can not be empty");
+            }
+
+            if (vectors.size() != 1) {
+                throw new ParamException("Only support one vector for each AnnSearchParam");
+            }
+
+            if (vectors.get(0) instanceof List) {
+                // float vectors
+                // TODO: here only check the first element, potential risk
+                List<?> first = (List<?>) vectors.get(0);
+                if (!(first.get(0) instanceof Float)) {
+                    throw new ParamException("Float vector field's value must be Lst<Float>");
+                }
+
+                int dim = first.size();
+                for (int i = 1; i < vectors.size(); ++i) {
+                    List<?> temp = (List<?>) vectors.get(i);
+                    if (dim != temp.size()) {
+                        throw new ParamException("Target vector dimension must be equal");
+                    }
+                }
+            } else if (vectors.get(0) instanceof ByteBuffer) {
+                // binary vectors
+                // TODO: here only check the first element, potential risk
+                ByteBuffer first = (ByteBuffer) vectors.get(0);
+                int dim = first.position();
+                for (int i = 1; i < vectors.size(); ++i) {
+                    ByteBuffer temp = (ByteBuffer) vectors.get(i);
+                    if (dim != temp.position()) {
+                        throw new ParamException("Target vector dimension must be equal");
+                    }
+                }
+            } else if (vectors.get(0) instanceof SortedMap) {
+                // sparse vectors, must be SortedMap<Long, Float>
+                // TODO: here only check the first element, potential risk
+                SortedMap<?, ?> map = (SortedMap<?, ?>) vectors.get(0);
+
+
+            } else {
+                String msg = "Search target vector type is illegal." +
+                        " Only allow List<Float> for FloatVector," +
+                        " ByteBuffer for BinaryVector/Float16Vector/BFloat16Vector," +
+                        " List<SortedMap<Long, Float>> for SparseFloatVector.";
+                throw new ParamException(msg);
+            }
+
+            return new AnnSearchParam(this);
+        }
+    }
+
+}

+ 236 - 0
src/main/java/io/milvus/param/dml/HybridSearchParam.java

@@ -0,0 +1,236 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package io.milvus.param.dml;
+
+import com.google.common.collect.Lists;
+import io.milvus.common.clientenum.ConsistencyLevelEnum;
+import io.milvus.exception.ParamException;
+import io.milvus.param.Constant;
+import io.milvus.param.MetricType;
+import io.milvus.param.ParamUtils;
+
+import io.milvus.param.dml.ranker.BaseRanker;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
+
+import java.nio.ByteBuffer;
+import java.util.List;
+import java.util.SortedMap;
+
+/**
+ * Parameters for <code>search</code> interface.
+ */
+@Getter
+@ToString
+public class HybridSearchParam {
+    private final String databaseName;
+    private final String collectionName;
+    private final List<String> partitionNames;
+    private final List<AnnSearchParam> searchRequests;
+    private final BaseRanker ranker;
+    private final int topK;
+    private final List<String> outFields;
+    private final int roundDecimal;
+    private final ConsistencyLevelEnum consistencyLevel;
+
+    private HybridSearchParam(@NonNull Builder builder) {
+        this.databaseName = builder.databaseName;
+        this.collectionName = builder.collectionName;
+        this.partitionNames = builder.partitionNames;
+        this.searchRequests = builder.searchRequests;
+        this.ranker = builder.ranker;
+        this.topK = builder.topK;
+        this.outFields = builder.outFields;
+        this.roundDecimal = builder.roundDecimal;
+        this.consistencyLevel = builder.consistencyLevel;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link SearchParam} class.
+     */
+    public static class Builder {
+        private String databaseName;
+        private String collectionName;
+        private final List<String> partitionNames = Lists.newArrayList();
+        private final List<AnnSearchParam> searchRequests = Lists.newArrayList();
+        private BaseRanker ranker = null;
+        private Integer topK;
+        private final List<String> outFields = Lists.newArrayList();
+        private Integer roundDecimal = -1;
+        private ConsistencyLevelEnum consistencyLevel = null;
+
+        Builder() {
+        }
+
+        /**
+         * Sets the database name. database name can be nil.
+         *
+         * @param databaseName database name
+         * @return <code>Builder</code>
+         */
+        public Builder withDatabaseName(String databaseName) {
+            this.databaseName = databaseName;
+            return this;
+        }
+
+        /**
+         * Sets the collection name. Collection name cannot be empty or null.
+         *
+         * @param collectionName collection name
+         * @return <code>Builder</code>
+         */
+        public Builder withCollectionName(@NonNull String collectionName) {
+            this.collectionName = collectionName;
+            return this;
+        }
+
+        /**
+         * Sets partition names list to specify search scope (Optional).
+         *
+         * @param partitionNames partition names list
+         * @return <code>Builder</code>
+         */
+        public Builder withPartitionNames(@NonNull List<String> partitionNames) {
+            partitionNames.forEach(this::addPartitionName);
+            return this;
+        }
+
+        /**
+         * Adds a partition to specify search scope (Optional).
+         *
+         * @param partitionName partition name
+         * @return <code>Builder</code>
+         */
+        public Builder addPartitionName(@NonNull String partitionName) {
+            if (!this.partitionNames.contains(partitionName)) {
+                this.partitionNames.add(partitionName);
+            }
+            return this;
+        }
+
+        /**
+         * Adds a vector search request for a vector field.
+         *
+         * @param searchParam vector search request
+         * @return <code>Builder</code>
+         */
+        public Builder addSearchRequest(@NonNull AnnSearchParam searchParam) {
+            this.searchRequests.add(searchParam);
+            return this;
+        }
+
+        /**
+         * Set a ranker for rearranging number of limit results.
+         *
+         * @param ranker concrete ranker object
+         * @return <code>Builder</code>
+         */
+        public Builder withRanker(@NonNull BaseRanker ranker) {
+            this.ranker = ranker;
+            return this;
+        }
+
+        /**
+         * ConsistencyLevel of consistency level.
+         *
+         * @param consistencyLevel consistency level
+         * @return <code>Builder</code>
+         */
+        public Builder withConsistencyLevel(ConsistencyLevelEnum consistencyLevel) {
+            this.consistencyLevel = consistencyLevel;
+            return this;
+        }
+
+        /**
+         * Sets topK value of ANN search.
+         *
+         * @param topK topK value
+         * @return <code>Builder</code>
+         */
+        public Builder withTopK(@NonNull Integer topK) {
+            this.topK = topK;
+            return this;
+        }
+
+        /**
+         * Specifies output fields (Optional).
+         *
+         * @param outFields output fields
+         * @return <code>Builder</code>
+         */
+        public Builder withOutFields(@NonNull List<String> outFields) {
+            outFields.forEach(this::addOutField);
+            return this;
+        }
+
+        /**
+         * Specifies an output field (Optional).
+         *
+         * @param fieldName filed name
+         * @return <code>Builder</code>
+         */
+        public Builder addOutField(@NonNull String fieldName) {
+            if (!this.outFields.contains(fieldName)) {
+                this.outFields.add(fieldName);
+            }
+            return this;
+        }
+
+        /**
+         * Specifies the decimal place of the returned results.
+         *
+         * @param decimal how many digits after the decimal point
+         * @return <code>Builder</code>
+         */
+        public Builder withRoundDecimal(@NonNull Integer decimal) {
+            this.roundDecimal = decimal;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link HybridSearchParam} instance.
+         *
+         * @return {@link HybridSearchParam}
+         */
+        public HybridSearchParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(collectionName, "Collection name");
+
+            if (ranker == null) {
+                throw new ParamException("Must specify a Ranker by withRanker()");
+            }
+
+            if (searchRequests.isEmpty()) {
+                throw new ParamException("At least a search request is required");
+            }
+
+            if (topK <= 0) {
+                throw new ParamException("TopK value is illegal");
+            }
+
+            return new HybridSearchParam(this);
+        }
+    }
+
+}

+ 19 - 0
src/main/java/io/milvus/param/dml/UpsertParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.dml;
 
 import com.alibaba.fastjson.JSONObject;

+ 27 - 0
src/main/java/io/milvus/param/dml/ranker/BaseRanker.java

@@ -0,0 +1,27 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package io.milvus.param.dml.ranker;
+
+import java.util.HashMap;
+import java.util.Map;
+
+public abstract class BaseRanker {
+    public abstract Map<String, String> getProperties();
+}

+ 94 - 0
src/main/java/io/milvus/param/dml/ranker/RRFRanker.java

@@ -0,0 +1,94 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package io.milvus.param.dml.ranker;
+
+import com.alibaba.fastjson.JSONObject;
+import java.util.HashMap;
+import java.util.Map;
+
+import io.milvus.exception.ParamException;
+import io.milvus.param.ParamUtils;
+
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
+
+/**
+ * The RRF reranking strategy, which merges results from multiple searches, favoring items that consistently appear.
+ */
+@Getter
+@ToString
+public class RRFRanker extends BaseRanker {
+    private final Integer k;
+
+    private RRFRanker(@NonNull Builder builder) {
+        this.k = builder.k;
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        JSONObject params = new JSONObject();
+        params.put("k", this.k);
+
+        Map<String, String> props = new HashMap<>();
+        props.put("strategy", "rrf");
+        props.put("params", params.toString());
+        return props;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link RRFRanker} class.
+     */
+    public static class Builder {
+        private Integer k = 60;
+
+        private Builder() {
+        }
+
+        /**
+         * Sets k factor for RRF. Value cannot be negative. Default value is 60.
+         * score = 1 / (k + float32(rank_i+1))
+         * rank_i is the rank in each field
+         *
+         * @param k factor value
+         * @return <code>Builder</code>
+         */
+        public Builder withK(@NonNull Integer k) {
+            this.k = k;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link RRFRanker} instance.
+         *
+         * @return {@link RRFRanker}
+         */
+        public RRFRanker build() throws ParamException {
+            if (k < 0) {
+                throw new ParamException("K value cannot be negative");
+            }
+            return new RRFRanker(this);
+        }
+    }
+}

+ 91 - 0
src/main/java/io/milvus/param/dml/ranker/WeightedRanker.java

@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package io.milvus.param.dml.ranker;
+
+import com.alibaba.fastjson.JSONObject;
+import io.milvus.exception.ParamException;
+
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
+
+import java.util.*;
+
+/**
+ * The Average Weighted Scoring reranking strategy, which prioritizes vectors based on relevance,
+ * averaging their significance.
+ */
+@Getter
+@ToString
+public class WeightedRanker extends BaseRanker {
+    private final List<Float> weights;
+
+    private WeightedRanker(@NonNull Builder builder) {
+        this.weights = builder.weights;
+    }
+
+    @Override
+    public Map<String, String> getProperties() {
+        JSONObject params = new JSONObject();
+        params.put("weights", this.weights);
+
+        Map<String, String> props = new HashMap<>();
+        props.put("strategy", "weighted");
+        props.put("params", params.toString());
+        return props;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link WeightedRanker} class.
+     */
+    public static class Builder {
+        private List<Float> weights = new ArrayList<>();
+
+        private Builder() {
+        }
+
+        /**
+         * Assign weights for each AnnSearchParam. The length of weights must be equal to number of AnnSearchParam.
+         * You can assign any float value for weight, the sum of weight values can exceed 1.
+         * The distance/similarity values of each field will be mapped into a range of [0,1],
+         * and score = sum(weights[i] * distance_i_in_[0,1])
+         *
+         * @param weights weight values
+         * @return <code>Builder</code>
+         */
+        public Builder withWeights(@NonNull List<Float> weights) {
+            this.weights = weights;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link WeightedRanker} instance.
+         *
+         * @return {@link WeightedRanker}
+         */
+        public WeightedRanker build() throws ParamException {
+            return new WeightedRanker(this);
+        }
+    }
+}

+ 19 - 0
src/main/java/io/milvus/param/role/AddUserToRoleParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.role;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/role/CreateRoleParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.role;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/role/DropRoleParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.role;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/role/GrantRolePrivilegeParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.role;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/role/RemoveUserFromRoleParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.role;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/role/RevokeRolePrivilegeParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.role;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/role/SelectGrantForRoleAndObjectParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.role;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/role/SelectGrantForRoleParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.role;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/role/SelectRoleParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.role;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/param/role/SelectUserParam.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.param.role;
 
 import io.milvus.exception.ParamException;

+ 19 - 0
src/main/java/io/milvus/response/BulkInsertResponseWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import io.milvus.exception.IllegalResponseException;

+ 39 - 0
src/main/java/io/milvus/response/DescCollResponseWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import io.milvus.exception.ParamException;
@@ -170,9 +189,11 @@ public class DescCollResponseWrapper {
     /**
      * Get the vector key field.
      * throw ParamException if the vector key field doesn't exist.
+     * This method is deprecated since Milvus supports multiple vector fields from v2.4
      *
      * @return {@link FieldType} schema of the vector key field
      */
+    @Deprecated
     public FieldType getVectorField() {
         CollectionSchema schema = response.getSchema();
         for (int i = 0; i < schema.getFieldsCount(); ++i) {
@@ -185,6 +206,24 @@ public class DescCollResponseWrapper {
         throw new ParamException("No vector key found.");
     }
 
+    /**
+     * Get all the vector key field. (Milvus supports multiple vector fields from v2.4)
+     *
+     * @return {@link FieldType} schema of the vector key field
+     */
+    public List<FieldType> getVectorFields() {
+        List<FieldType> vectorFields = new ArrayList<>();
+        CollectionSchema schema = response.getSchema();
+        for (int i = 0; i < schema.getFieldsCount(); ++i) {
+            FieldSchema field = schema.getFields(i);
+            if (ParamUtils.isVectorDataType(field.getDataType())) {
+                vectorFields.add(ParamUtils.ConvertField(field));
+            }
+        }
+
+        return vectorFields;
+    }
+
     /**
      * Get properties of the collection.
      *

+ 19 - 0
src/main/java/io/milvus/response/DescIndexResponseWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import io.milvus.grpc.IndexDescription;

+ 19 - 0
src/main/java/io/milvus/response/FieldDataWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import com.alibaba.fastjson.JSONObject;

+ 19 - 0
src/main/java/io/milvus/response/GetBulkInsertStateWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import io.milvus.exception.IllegalResponseException;

+ 19 - 0
src/main/java/io/milvus/response/GetCollStatResponseWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import io.milvus.grpc.GetCollectionStatisticsResponse;

+ 19 - 0
src/main/java/io/milvus/response/GetPartStatResponseWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import io.milvus.grpc.GetPartitionStatisticsResponse;

+ 19 - 0
src/main/java/io/milvus/response/MutationResultWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import com.google.common.collect.Lists;

+ 19 - 0
src/main/java/io/milvus/response/QueryResultsWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import com.alibaba.fastjson.JSONObject;

+ 19 - 0
src/main/java/io/milvus/response/SearchResultsWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import com.alibaba.fastjson.JSONObject;

+ 19 - 0
src/main/java/io/milvus/response/ShowCollResponseWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import io.milvus.exception.IllegalResponseException;

+ 19 - 0
src/main/java/io/milvus/response/ShowPartResponseWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response;
 
 import io.milvus.exception.IllegalResponseException;

+ 19 - 0
src/main/java/io/milvus/response/basic/RowRecordWrapper.java

@@ -1,3 +1,22 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
 package io.milvus.response.basic;
 
 import com.alibaba.fastjson.JSONObject;

+ 162 - 4
src/test/java/io/milvus/client/MilvusClientDockerTest.java

@@ -20,6 +20,7 @@
 package io.milvus.client;
 
 import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.ListenableFuture;
 import io.milvus.common.clientenum.ConsistencyLevelEnum;
 import io.milvus.grpc.*;
@@ -29,10 +30,9 @@ import io.milvus.param.alias.CreateAliasParam;
 import io.milvus.param.alias.DropAliasParam;
 import io.milvus.param.alias.ListAliasesParam;
 import io.milvus.param.collection.*;
-import io.milvus.param.dml.InsertParam;
-import io.milvus.param.dml.QueryParam;
-import io.milvus.param.dml.SearchParam;
-import io.milvus.param.dml.UpsertParam;
+import io.milvus.param.dml.*;
+import io.milvus.param.dml.ranker.RRFRanker;
+import io.milvus.param.dml.ranker.WeightedRanker;
 import io.milvus.param.highlevel.dml.DeleteIdsParam;
 import io.milvus.param.highlevel.dml.GetIdsParam;
 import io.milvus.param.highlevel.dml.response.DeleteResponse;
@@ -796,6 +796,164 @@ class MilvusClientDockerTest {
         Assertions.assertEquals(R.Status.Success.getCode(), dropR.getStatus().intValue());
     }
 
+    @Test
+    void testMultipleVectorFields() {
+        String randomCollectionName = generator.generate(10);
+
+        // collection schema
+        String idField = "id";
+        String floatVectorField = "float_vector";
+        String binaryVectorField = "binary_vector";
+        String sparseVectorField = "sparse_vector";
+        FieldType field1 = FieldType.newBuilder()
+                .withPrimaryKey(true)
+                .withAutoID(true)
+                .withDataType(DataType.Int64)
+                .withName(idField)
+                .build();
+
+        FieldType field2 = FieldType.newBuilder()
+                .withDataType(DataType.FloatVector)
+                .withName(floatVectorField)
+                .withDimension(dimension)
+                .build();
+
+        FieldType field3 = FieldType.newBuilder()
+                .withDataType(DataType.BinaryVector)
+                .withName(binaryVectorField)
+                .withDimension(dimension)
+                .build();
+
+        FieldType field4 = FieldType.newBuilder()
+                .withDataType(DataType.SparseFloatVector)
+                .withName(sparseVectorField)
+                .build();
+
+        // create collection
+        CreateCollectionParam createParam = CreateCollectionParam.newBuilder()
+                .withCollectionName(randomCollectionName)
+                .withFieldTypes(Lists.newArrayList(field1, field2, field3, field4))
+                .build();
+
+        R<RpcStatus> createR = client.createCollection(createParam);
+        Assertions.assertEquals(R.Status.Success.getCode(), createR.getStatus().intValue());
+
+        // insert data to multiple vector fields
+        int rowCount = 10000;
+        List<List<Float>> floatVectors = generateFloatVectors(rowCount);
+        List<ByteBuffer> binaryVectors = generateBinaryVectors(rowCount);
+        List<SortedMap<Long, Float>> sparseVectors = generateSparseVectors(rowCount);
+
+        List<InsertParam.Field> fields = new ArrayList<>();
+        fields.add(new InsertParam.Field(floatVectorField, floatVectors));
+        fields.add(new InsertParam.Field(binaryVectorField, binaryVectors));
+        fields.add(new InsertParam.Field(sparseVectorField, sparseVectors));
+
+        InsertParam insertParam = InsertParam.newBuilder()
+                .withCollectionName(randomCollectionName)
+                .withFields(fields)
+                .build();
+
+        R<MutationResult> insertR = client.insert(insertParam);
+        Assertions.assertEquals(R.Status.Success.getCode(), insertR.getStatus().intValue());
+
+        // create indexes on multiple vector fields
+        CreateIndexParam indexParam = CreateIndexParam.newBuilder()
+                .withCollectionName(randomCollectionName)
+                .withFieldName(floatVectorField)
+                .withIndexType(IndexType.IVF_FLAT)
+                .withMetricType(MetricType.COSINE)
+                .withExtraParam("{\"nlist\":64}")
+                .build();
+
+        R<RpcStatus> createIndexR = client.createIndex(indexParam);
+        Assertions.assertEquals(R.Status.Success.getCode(), createIndexR.getStatus().intValue());
+
+        indexParam = CreateIndexParam.newBuilder()
+                .withCollectionName(randomCollectionName)
+                .withFieldName(binaryVectorField)
+                .withIndexType(IndexType.BIN_FLAT)
+                .withMetricType(MetricType.HAMMING)
+                .withExtraParam("{}")
+                .build();
+
+        createIndexR = client.createIndex(indexParam);
+        Assertions.assertEquals(R.Status.Success.getCode(), createIndexR.getStatus().intValue());
+
+        indexParam = CreateIndexParam.newBuilder()
+                .withCollectionName(randomCollectionName)
+                .withFieldName(sparseVectorField)
+                .withIndexType(IndexType.SPARSE_INVERTED_INDEX)
+                .withMetricType(MetricType.IP)
+                .withExtraParam("{\"drop_ratio_build\":0.2}")
+                .build();
+
+        createIndexR = client.createIndex(indexParam);
+        Assertions.assertEquals(R.Status.Success.getCode(), createIndexR.getStatus().intValue());
+
+        // load collection
+        R<RpcStatus> loadR = client.loadCollection(LoadCollectionParam.newBuilder()
+                .withCollectionName(randomCollectionName)
+                .build());
+        Assertions.assertEquals(R.Status.Success.getCode(), loadR.getStatus().intValue());
+
+        // search on multiple vector fields
+        AnnSearchParam param1 = AnnSearchParam.newBuilder()
+                .withVectorFieldName(floatVectorField)
+                .withVectors(generateFloatVectors(1))
+                .withMetricType(MetricType.COSINE)
+                .withParams("{\"nprobe\": 32}")
+                .withTopK(10)
+                .build();
+
+        AnnSearchParam param2 = AnnSearchParam.newBuilder()
+                .withVectorFieldName(binaryVectorField)
+                .withVectors(generateBinaryVectors(1))
+                .withMetricType(MetricType.HAMMING)
+                .withParams("{}")
+                .withTopK(5)
+                .build();
+
+        AnnSearchParam param3 = AnnSearchParam.newBuilder()
+                .withVectorFieldName(sparseVectorField)
+                .withVectors(generateSparseVectors(1))
+                .withMetricType(MetricType.IP)
+                .withParams("{\"drop_ratio_search\":0.2}")
+                .withTopK(7)
+                .build();
+
+        HybridSearchParam searchParam = HybridSearchParam.newBuilder()
+                .withCollectionName(randomCollectionName)
+                .addOutField(sparseVectorField)
+                .addSearchRequest(param1)
+                .addSearchRequest(param2)
+                .addSearchRequest(param3)
+                .withTopK(3)
+                .withConsistencyLevel(ConsistencyLevelEnum.STRONG)
+                .withRanker(WeightedRanker.newBuilder()
+                        .withWeights(Lists.newArrayList(0.5f, 0.5f, 1.0f))
+                        .build())
+                .build();
+
+        R<SearchResults> searchR = client.hybridSearch(searchParam);
+        Assertions.assertEquals(R.Status.Success.getCode(), searchR.getStatus().intValue());
+
+        // print search result
+        SearchResultsWrapper results = new SearchResultsWrapper(searchR.getData().getResults());
+        List<SearchResultsWrapper.IDScore> scores = results.getIDScore(0);
+        for (int i = 0; i < scores.size(); ++i) {
+            System.out.println(scores.get(i));
+        }
+
+        // drop collection
+        DropCollectionParam dropParam = DropCollectionParam.newBuilder()
+                .withCollectionName(randomCollectionName)
+                .build();
+
+        R<RpcStatus> dropR = client.dropCollection(dropParam);
+        Assertions.assertEquals(R.Status.Success.getCode(), dropR.getStatus().intValue());
+    }
+
     @Test
     void testAsyncMethods() {
         String randomCollectionName = generator.generate(10);

+ 49 - 0
src/test/java/io/milvus/client/MilvusServiceClientTest.java

@@ -34,6 +34,8 @@ import io.milvus.param.collection.*;
 import io.milvus.param.control.*;
 import io.milvus.param.credential.*;
 import io.milvus.param.dml.*;
+import io.milvus.param.dml.ranker.BaseRanker;
+import io.milvus.param.dml.ranker.RRFRanker;
 import io.milvus.param.index.*;
 import io.milvus.param.partition.*;
 import io.milvus.response.*;
@@ -2182,6 +2184,53 @@ class MilvusServiceClientTest {
         testAsyncFuncByName("searchAsync", param);
     }
 
+    @Test
+    void hybridSearch() {
+        List<List<Float>> vectors = new ArrayList<>();
+        List<Float> vector1 = Arrays.asList(0.1f, 0.2f);
+        vectors.add(vector1);
+        AnnSearchParam param1 = AnnSearchParam.newBuilder()
+                .withParams("{}")
+                .withVectorFieldName("field1")
+                .withMetricType(MetricType.IP)
+                .withTopK(5)
+                .withVectors(vectors)
+                .withExpr("dummy")
+                .build();
+
+        List<ByteBuffer> bVectors = new ArrayList<>();
+        ByteBuffer buf = ByteBuffer.allocate(2);
+        buf.put((byte) 1);
+        buf.put((byte) 2);
+        bVectors.add(buf);
+        AnnSearchParam param2 = AnnSearchParam.newBuilder()
+                .withParams("{}")
+                .withVectorFieldName("field2")
+                .withMetricType(MetricType.HAMMING)
+                .withTopK(5)
+                .withVectors(bVectors)
+                .withExpr("dummy")
+                .build();
+
+        List<String> partitions = Collections.singletonList("partition1");
+        List<String> outputFields = Collections.singletonList("field2");
+        HybridSearchParam param = HybridSearchParam.newBuilder()
+                .withCollectionName("collection1")
+                .withPartitionNames(partitions)
+                .withOutFields(outputFields)
+                .addOutField("f2")
+                .addSearchRequest(param1)
+                .addSearchRequest(param2)
+                .withTopK(15)
+                .withRoundDecimal(5)
+                .withConsistencyLevel(ConsistencyLevelEnum.EVENTUALLY)
+                .withRanker(RRFRanker.newBuilder().withK(10).build())
+                .build();
+
+        testFuncByName("hybridSearch", param);
+        testAsyncFuncByName("hybridSearchAsync", param);
+    }
+
     @Test
     void queryParam() {
         // test throw exception with illegal input

部分文件因为文件数量过多而无法显示