Browse Source

add high-level support & updatePwd oldPwd can be empty (#535)

xushuang.hu 2 years ago
parent
commit
2d222ab78b
30 changed files with 2090 additions and 85 deletions
  1. 259 0
      examples/main/java/io/milvus/HighLevelExample.java
  2. 293 9
      src/main/java/io/milvus/client/AbstractMilvusGrpcClient.java
  3. 66 0
      src/main/java/io/milvus/client/MilvusClient.java
  4. 52 0
      src/main/java/io/milvus/client/MilvusMultiServiceClient.java
  5. 2 0
      src/main/java/io/milvus/client/MilvusServiceClient.java
  6. 36 0
      src/main/java/io/milvus/common/utils/VectorUtils.java
  7. 10 0
      src/main/java/io/milvus/param/Constant.java
  8. 13 0
      src/main/java/io/milvus/param/ParamUtils.java
  9. 1 1
      src/main/java/io/milvus/param/credential/UpdateCredentialParam.java
  10. 9 2
      src/main/java/io/milvus/param/dml/InsertParam.java
  11. 1 1
      src/main/java/io/milvus/param/dml/SearchParam.java
  12. 212 0
      src/main/java/io/milvus/param/highlevel/collection/CreateSimpleCollectionParam.java
  13. 63 0
      src/main/java/io/milvus/param/highlevel/collection/ListCollectionsParam.java
  14. 34 0
      src/main/java/io/milvus/param/highlevel/collection/response/ListCollectionsResponse.java
  15. 108 0
      src/main/java/io/milvus/param/highlevel/dml/DeleteIdsParam.java
  16. 122 0
      src/main/java/io/milvus/param/highlevel/dml/GetIdsParam.java
  17. 103 0
      src/main/java/io/milvus/param/highlevel/dml/InsertRowsParam.java
  18. 147 0
      src/main/java/io/milvus/param/highlevel/dml/QuerySimpleParam.java
  19. 175 0
      src/main/java/io/milvus/param/highlevel/dml/SearchSimpleParam.java
  20. 36 0
      src/main/java/io/milvus/param/highlevel/dml/response/DeleteResponse.java
  21. 35 0
      src/main/java/io/milvus/param/highlevel/dml/response/GetResponse.java
  22. 35 0
      src/main/java/io/milvus/param/highlevel/dml/response/InsertResponse.java
  23. 35 0
      src/main/java/io/milvus/param/highlevel/dml/response/QueryResponse.java
  24. 35 0
      src/main/java/io/milvus/param/highlevel/dml/response/SearchResponse.java
  25. 38 0
      src/main/java/io/milvus/response/DescCollResponseWrapper.java
  26. 15 0
      src/main/java/io/milvus/response/MutationResultWrapper.java
  27. 31 71
      src/main/java/io/milvus/response/QueryResultsWrapper.java
  28. 39 1
      src/main/java/io/milvus/response/SearchResultsWrapper.java
  29. 4 0
      src/main/java/io/milvus/response/ShowCollResponseWrapper.java
  30. 81 0
      src/main/java/io/milvus/response/basic/RowRecordWrapper.java

+ 259 - 0
examples/main/java/io/milvus/HighLevelExample.java

@@ -0,0 +1,259 @@
+/*
+ * 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;
+
+import com.alibaba.fastjson.JSONObject;
+import com.google.common.collect.Lists;
+import io.milvus.client.MilvusServiceClient;
+import io.milvus.common.utils.JacksonUtils;
+import io.milvus.common.utils.VectorUtils;
+import io.milvus.grpc.*;
+import io.milvus.param.*;
+import io.milvus.param.collection.*;
+import io.milvus.param.highlevel.collection.response.ListCollectionsResponse;
+import io.milvus.param.highlevel.collection.CreateSimpleCollectionParam;
+import io.milvus.param.highlevel.collection.ListCollectionsParam;
+import io.milvus.param.highlevel.dml.*;
+import io.milvus.param.highlevel.dml.response.*;
+import io.milvus.response.*;
+
+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;
+
+    static {
+        ConnectParam connectParam = ConnectParam.newBuilder()
+                .withUri("https://in01-a00c28dbbf13e49.aws-us-west-2.vectordb-uat3.zillizcloud.com:19535")
+                .withAuthorization("db_admin","Easou!234")
+                .build();
+        milvusClient = new MilvusServiceClient(connectParam);
+    }
+
+    private static final String COLLECTION_NAME = "HIGH_LEVEL";
+    private static final String ID_FIELD = "userID";
+    private static final String VECTOR_FIELD = "userFace";
+    private static final String USER_JSON_FIELD = "userJson";
+    private static final Integer VECTOR_DIM = 36;
+    private static final String AGE_FIELD = "userAge";
+
+    private static final String INDEX_NAME = "userFaceIndex";
+    private static final IndexType INDEX_TYPE = IndexType.IVF_FLAT;
+    private static final String INDEX_PARAM = "{\"nlist\":128}";
+
+    private static final String INT32_FIELD_NAME = "int32";
+    private static final String INT64_FIELD_NAME = "int64";
+    private static final String VARCHAR_FIELD_NAME = "varchar";
+    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);
+        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 ==========");
+        CreateSimpleCollectionParam createSimpleCollectionParam = CreateSimpleCollectionParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withDimension(VECTOR_DIM)
+                .withPrimaryField(ID_FIELD)
+                .withVectorField(VECTOR_FIELD)
+                .withAutoId(true)
+                .build();
+
+        R<RpcStatus> response = milvusClient.createCollection(createSimpleCollectionParam);
+        handleResponseStatus(response);
+        System.out.println(JacksonUtils.toJsonString(response.getData()));
+        return response;
+    }
+
+    private R<ListCollectionsResponse> listCollections() {
+        System.out.println("========== high level listCollections ==========");
+        ListCollectionsParam listCollectionsParam = ListCollectionsParam.newBuilder()
+                .build();
+
+        R<ListCollectionsResponse> response = milvusClient.listCollections(listCollectionsParam);
+        handleResponseStatus(response);
+        System.out.println(response);
+        return response;
+    }
+
+    private R<InsertResponse> insertRows(int rowCount) {
+        System.out.println("========== high level insertRows ==========");
+        List<JSONObject> rowsData = new ArrayList<>();
+        Random ran = new Random();
+        for (long i = 0L; i < rowCount; ++i) {
+            JSONObject row = new JSONObject();
+            row.put(AGE_FIELD, ran.nextInt(99));
+            row.put(VECTOR_FIELD, generateFloatVector());
+
+            // $meta if collection EnableDynamicField, you can input this field not exist in schema, else deny
+            row.put(INT32_FIELD_NAME, ran.nextInt());
+            row.put(INT64_FIELD_NAME, ran.nextLong());
+            row.put(VARCHAR_FIELD_NAME, "测试varchar");
+            row.put(FLOAT_FIELD_NAME, ran.nextFloat());
+            row.put(DOUBLE_FIELD_NAME, ran.nextDouble());
+            row.put(BOOL_FIELD_NAME, ran.nextBoolean());
+
+            // $json
+            JSONObject jsonObject = new JSONObject();
+            jsonObject.put(INT32_FIELD_NAME, ran.nextInt());
+            jsonObject.put(INT64_FIELD_NAME, ran.nextLong());
+            jsonObject.put(VARCHAR_FIELD_NAME, "测试varchar");
+            jsonObject.put(FLOAT_FIELD_NAME, ran.nextFloat());
+            jsonObject.put(DOUBLE_FIELD_NAME, ran.nextDouble());
+            jsonObject.put(BOOL_FIELD_NAME, ran.nextBoolean());
+            row.put(USER_JSON_FIELD, jsonObject);
+
+            rowsData.add(row);
+        }
+
+        InsertRowsParam insertRowsParam = InsertRowsParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withRows(rowsData)
+                .build();
+
+        R<InsertResponse> response = milvusClient.insert(insertRowsParam);
+        handleResponseStatus(response);
+        System.out.println("insertCount: " + response.getData().getInsertCount());
+        System.out.println("insertIds: " + response.getData().getInsertIds());
+        return response;
+    }
+
+    private R<DeleteResponse> delete(List<?> ids) {
+        System.out.println("========== high level insertRows ==========");
+        DeleteIdsParam deleteIdsParam = DeleteIdsParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withPrimaryIds(ids)
+                .build();
+
+        R<DeleteResponse> response = milvusClient.delete(deleteIdsParam);
+        handleResponseStatus(response);
+        System.out.println(response);
+        return response;
+    }
+
+    private R<GetResponse> get(List<?> ids) {
+        System.out.println("========== high level get ==========");
+        GetIdsParam getParam = GetIdsParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withPrimaryIds(ids)
+                .build();
+
+        R<GetResponse> response = milvusClient.get(getParam);
+        handleResponseStatus(response);
+        for (QueryResultsWrapper.RowRecord rowRecord : response.getData().getRowRecords()) {
+            System.out.println(rowRecord);
+        }
+        return response;
+    }
+
+    private R<SearchResponse> searchSimple(String filter) {
+        System.out.println("========== high level search ==========");
+        SearchSimpleParam searchSimpleParam = SearchSimpleParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withVectors(generateFloatVector())
+                .withFilter(filter)
+                .withLimit(100)
+                .withOffset(0L)
+                .withOutputFields(Lists.newArrayList("int32", "int64"))
+                .build();
+
+        R<SearchResponse> response = milvusClient.search(searchSimpleParam);
+        handleResponseStatus(response);
+        for (QueryResultsWrapper.RowRecord rowRecord : response.getData().getRowRecords()) {
+            System.out.println(rowRecord);
+        }
+        return response;
+    }
+
+    private R<QueryResponse> querySimple(String filter) {
+        System.out.println("========== high level query ==========");
+        QuerySimpleParam querySimpleParam = QuerySimpleParam.newBuilder()
+                .withCollectionName(COLLECTION_NAME)
+                .withFilter(filter)
+                .withLimit(100L)
+                .withOffset(0L)
+                .build();
+
+        R<QueryResponse> response = milvusClient.query(querySimpleParam);
+        handleResponseStatus(response);
+        for (QueryResultsWrapper.RowRecord rowRecord : response.getData().getRowRecords()) {
+            System.out.println(rowRecord);
+        }
+        return response;
+    }
+
+    public static void main(String[] args) {
+        HighLevelExample example = new HighLevelExample();
+        example.createCollection();
+        example.listCollections();
+
+        R<DescribeCollectionResponse> describeCollectionResponseR = example.describeCollection();
+        DescCollResponseWrapper descCollResponseWrapper = new DescCollResponseWrapper(describeCollectionResponseR.getData());
+
+        int dataCount = 5;
+        R<InsertResponse> insertResponse = example.insertRows(dataCount);
+
+        List<?> insertIds = insertResponse.getData().getInsertIds();
+        example.get(insertIds);
+
+        String expr = VectorUtils.convertPksExpr(insertIds, descCollResponseWrapper);
+        example.querySimple(expr);
+        example.searchSimple(expr);
+
+        // Asynchronous deletion. A successful response does not guarantee immediate data deletion. Please wait for a certain period of time for the deletion operation to take effect.
+        example.delete(insertIds);
+    }
+
+}

+ 293 - 9
src/main/java/io/milvus/client/AbstractMilvusGrpcClient.java

@@ -19,43 +19,46 @@
 
 package io.milvus.client;
 
+import com.google.common.collect.Lists;
 import com.google.common.util.concurrent.FutureCallback;
 import com.google.common.util.concurrent.Futures;
 import com.google.common.util.concurrent.ListenableFuture;
 import com.google.common.util.concurrent.MoreExecutors;
 import io.grpc.StatusRuntimeException;
+import io.milvus.common.clientenum.ConsistencyLevelEnum;
+import io.milvus.common.utils.JacksonUtils;
+import io.milvus.common.utils.VectorUtils;
 import io.milvus.exception.*;
 import io.milvus.grpc.*;
 import io.milvus.grpc.ObjectEntity;
+import io.milvus.param.Constant;
 import io.milvus.param.ParamUtils;
 import io.milvus.param.R;
 import io.milvus.param.RpcStatus;
 import io.milvus.param.alias.*;
 import io.milvus.param.bulkinsert.*;
 import io.milvus.param.collection.*;
+import io.milvus.param.highlevel.collection.response.ListCollectionsResponse;
 import io.milvus.param.control.*;
 import io.milvus.param.credential.*;
 import io.milvus.param.dml.*;
+import io.milvus.param.highlevel.collection.CreateSimpleCollectionParam;
+import io.milvus.param.highlevel.collection.ListCollectionsParam;
+import io.milvus.param.highlevel.dml.*;
+import io.milvus.param.highlevel.dml.response.*;
 import io.milvus.param.index.*;
 import io.milvus.param.partition.*;
 import io.milvus.param.role.*;
-import io.milvus.response.DescCollResponseWrapper;
+import io.milvus.response.*;
 import lombok.NonNull;
 import org.apache.commons.collections4.CollectionUtils;
-import org.apache.commons.collections4.MapUtils;
 import org.apache.commons.lang3.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
 import javax.annotation.Nonnull;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Base64;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.Optional;
+import java.util.*;
 import java.util.concurrent.TimeUnit;
 import java.util.function.Function;
 
@@ -2719,6 +2722,287 @@ public abstract class AbstractMilvusGrpcClient implements MilvusClient {
         }
     }
 
+    ///////////////////// High Level API//////////////////////
+    @Override
+    public R<RpcStatus> createCollection(CreateSimpleCollectionParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+        logInfo(requestParam.toString());
+        
+        try {
+            // step1: create collection
+            R<RpcStatus> createCollectionStatus = createCollection(requestParam.getCreateCollectionParam());
+            if(!Objects.equals(createCollectionStatus.getStatus(), R.success().getStatus())){
+                logError("CreateCollection failed: {}", createCollectionStatus.getException().getMessage());
+                return R.failed(createCollectionStatus.getException());
+            }
+
+            // step2: create index
+            R<RpcStatus> createIndexStatus = createIndex(requestParam.getCreateIndexParam());
+            if(!Objects.equals(createIndexStatus.getStatus(), R.success().getStatus())){
+                logError("CreateIndex failed: {}", createIndexStatus.getException().getMessage());
+                return R.failed(createIndexStatus.getException());
+            }
+
+            // step3: load collection
+            R<RpcStatus> loadCollectionStatus = loadCollection(requestParam.getLoadCollectionParam());
+            if(!Objects.equals(loadCollectionStatus.getStatus(), R.success().getStatus())){
+                logError("LoadCollection failed: {}", loadCollectionStatus.getException().getMessage());
+                return R.failed(loadCollectionStatus.getException());
+            }
+
+            logDebug("CreateCollection successfully!");
+            return R.success(new RpcStatus(RpcStatus.SUCCESS_MSG));
+        } catch (StatusRuntimeException e) {
+            logError("CreateCollection RPC failed!", e.getStatus().toString());
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("CreateCollection failed! ", e.getMessage());
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public R<ListCollectionsResponse> listCollections(ListCollectionsParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+        logInfo(requestParam.toString());
+        
+        try {
+            R<ShowCollectionsResponse> response = showCollections(requestParam.getShowCollectionsParam());
+            if(!Objects.equals(response.getStatus(), R.success().getStatus())){
+                logError("ListCollections failed: {}", response.getException().getMessage());
+                return R.failed(response.getException());
+            }
+
+            ShowCollResponseWrapper showCollResponseWrapper = new ShowCollResponseWrapper(response.getData());
+            return R.success(ListCollectionsResponse.builder()
+                    .collectionNames(showCollResponseWrapper.getCollectionNames()).build());
+        } catch (StatusRuntimeException e) {
+            logError("ListCollections RPC failed!", e.getStatus().toString());
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("ListCollections failed! ", e.getMessage());
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public R<InsertResponse> insert(InsertRowsParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+        logInfo(requestParam.toString());
+        
+        try {
+            R<MutationResult> response = insert(requestParam.getInsertParam());
+            if(!Objects.equals(response.getStatus(), R.success().getStatus())){
+                logError("Insert failed: {}", response.getException().getMessage());
+                return R.failed(response.getException());
+            }
+
+            logDebug("Insert successfully!");
+            MutationResultWrapper wrapper = new MutationResultWrapper(response.getData());
+            return R.success(InsertResponse.builder().insertIds(wrapper.getInsertIDs()).insertCount(wrapper.getInsertCount()).build());
+        } catch (StatusRuntimeException e) {
+            logError("Insert RPC failed!", e.getStatus().toString());
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("Insert failed! ", e.getMessage());
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public R<DeleteResponse> delete(DeleteIdsParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+        logInfo(requestParam.toString());
+
+        try {
+            DescribeCollectionParam.Builder builder = DescribeCollectionParam.newBuilder()
+                    .withCollectionName(requestParam.getCollectionName());
+            R<DescribeCollectionResponse> descResp = describeCollection(builder.build());
+            if (descResp.getStatus() != R.Status.Success.getCode()) {
+                logError("Failed to describe collection: {}", requestParam.getCollectionName());
+                return R.failed(R.Status.valueOf(descResp.getStatus()), descResp.getMessage());
+            }
+            DescCollResponseWrapper wrapper = new DescCollResponseWrapper(descResp.getData());
+
+            String expr = VectorUtils.convertPksExpr(requestParam.getPrimaryIds(), wrapper);
+            DeleteParam deleteParam = DeleteParam.newBuilder()
+                    .withCollectionName(requestParam.getCollectionName())
+                    .withExpr(expr)
+                    .build();
+            R<MutationResult> resultR = delete(deleteParam);
+            MutationResultWrapper resultWrapper = new MutationResultWrapper(resultR.getData());
+            return R.success(DeleteResponse.builder().deleteIds(resultWrapper.getInsertIDs()).build());
+        } catch (StatusRuntimeException e) {
+            logError("Delete RPC failed! Collection name:{}\n{}",
+                    requestParam.getCollectionName(), e.getMessage());
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("Delete failed! Collection name:{}\n{}",
+                    requestParam.getCollectionName(), e.getMessage());
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public R<GetResponse> get(GetIdsParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+        logInfo(requestParam.toString());
+
+        try {
+            DescribeCollectionParam.Builder builder = DescribeCollectionParam.newBuilder()
+                    .withCollectionName(requestParam.getCollectionName());
+            R<DescribeCollectionResponse> descResp = describeCollection(builder.build());
+
+            if (descResp.getStatus() != R.Status.Success.getCode()) {
+                logError("Failed to describe collection: {}", requestParam.getCollectionName());
+                return R.failed(R.Status.valueOf(descResp.getStatus()), descResp.getMessage());
+            }
+
+            DescCollResponseWrapper wrapper = new DescCollResponseWrapper(descResp.getData());
+            FieldType primaryField = wrapper.getPrimaryField();
+
+            if (CollectionUtils.isEmpty(requestParam.getOutputFields())) {
+                FieldType vectorField = wrapper.getVectorField();
+                requestParam.getOutputFields().addAll(Lists.newArrayList(Constant.ALL_OUTPUT_FIELDS, vectorField.getName()));
+            }
+
+            String expr = VectorUtils.convertPksExpr(requestParam.getPrimaryIds(), primaryField.getName());
+            QueryParam queryParam = QueryParam.newBuilder()
+                    .withCollectionName(requestParam.getCollectionName())
+                    .withExpr(expr)
+                    .withOutFields(requestParam.getOutputFields())
+                    .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED)
+                    .build();
+            R<QueryResults> queryResp = query(queryParam);
+            QueryResultsWrapper queryResultsWrapper = new QueryResultsWrapper(queryResp.getData());
+            return R.success(GetResponse.builder().rowRecords(queryResultsWrapper.getRowRecords()).build());
+        } catch (StatusRuntimeException e) {
+            logError("Get RPC failed! Collection name:{}\n{}",
+                    requestParam.getCollectionName(), e.getMessage());
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("Get failed! Collection name:{}\n{}",
+                    requestParam.getCollectionName(), e.getMessage());
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public R<QueryResponse> query(QuerySimpleParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+        logInfo(requestParam.toString());
+
+        try {
+            DescribeCollectionParam.Builder builder = DescribeCollectionParam.newBuilder()
+                    .withCollectionName(requestParam.getCollectionName());
+            R<DescribeCollectionResponse> descResp = describeCollection(builder.build());
+            if (descResp.getStatus() != R.Status.Success.getCode()) {
+                logError("Failed to describe collection: {}", requestParam.getCollectionName());
+                return R.failed(R.Status.valueOf(descResp.getStatus()), descResp.getMessage());
+            }
+
+            DescCollResponseWrapper descCollWrapper = new DescCollResponseWrapper(descResp.getData());
+            if (CollectionUtils.isEmpty(requestParam.getOutputFields())) {
+                FieldType vectorField = descCollWrapper.getVectorField();
+                requestParam.getOutputFields().addAll(Lists.newArrayList(Constant.ALL_OUTPUT_FIELDS, vectorField.getName()));
+            }
+
+            QueryParam queryParam = QueryParam.newBuilder()
+                    .withCollectionName(requestParam.getCollectionName())
+                    .withExpr(requestParam.getFilter())
+                    .withOutFields(requestParam.getOutputFields())
+                    .withOffset(requestParam.getOffset())
+                    .withLimit(requestParam.getLimit())
+                    .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED)
+                    .build();
+            R<QueryResults> response = query(queryParam);
+            if(!Objects.equals(response.getStatus(), R.success().getStatus())){
+                logError("Query failed: {}", response.getException().getMessage());
+                return R.failed(response.getException());
+            }
+
+            QueryResultsWrapper queryWrapper = new QueryResultsWrapper(response.getData());
+            return R.success(QueryResponse.builder().rowRecords(queryWrapper.getRowRecords()).build());
+        } catch (StatusRuntimeException e) {
+            logError("Query RPC failed!", e.getStatus().toString());
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("Query failed! ", e.getMessage());
+            return R.failed(e);
+        }
+    }
+
+    @Override
+    public R<SearchResponse> search(SearchSimpleParam requestParam) {
+        if (!clientIsReady()) {
+            return R.failed(new ClientNotConnectedException("Client rpc channel is not ready"));
+        }
+        logInfo(requestParam.toString());
+
+        try {
+            DescribeCollectionParam.Builder builder = DescribeCollectionParam.newBuilder()
+                    .withCollectionName(requestParam.getCollectionName());
+            R<DescribeCollectionResponse> descResp = describeCollection(builder.build());
+
+            if (descResp.getStatus() != R.Status.Success.getCode()) {
+                logError("Failed to describe collection: {}", requestParam.getCollectionName());
+                return R.failed(R.Status.valueOf(descResp.getStatus()), descResp.getMessage());
+            }
+
+            DescCollResponseWrapper wrapper = new DescCollResponseWrapper(descResp.getData());
+            FieldType vectorField = wrapper.getVectorField();
+
+            // fill in vectorData
+            List<List<?>> vectors = new ArrayList<>();
+            if (requestParam.getVectors().get(0) instanceof List) {
+                vectors = (List<List<?>>) requestParam.getVectors();
+            } else {
+                vectors.add(requestParam.getVectors());
+            }
+
+            SearchParam searchParam = SearchParam.newBuilder()
+                    .withCollectionName(requestParam.getCollectionName())
+                    .withVectors(vectors)
+                    .withVectorFieldName(vectorField.getName())
+                    .withOutFields(requestParam.getOutputFields())
+                    .withExpr(requestParam.getFilter())
+                    .withTopK(requestParam.getLimit())
+                    .withParams(JacksonUtils.toJsonString(requestParam.getParams()))
+                    .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED)
+                    .build();
+
+            // search
+            R<SearchResults> response = search(searchParam);
+            if(!Objects.equals(response.getStatus(), R.success().getStatus())){
+                logError("Search failed: {}", response.getException().getMessage());
+                return R.failed(response.getException());
+            }
+
+            SearchResultsWrapper searchResultsWrapper = new SearchResultsWrapper(response.getData().getResults());
+            return R.success(SearchResponse.builder().rowRecords(searchResultsWrapper.getRowRecords()).build());
+        } catch (StatusRuntimeException e) {
+            logError("Search RPC failed! Collection name:{}\n{}",
+                    requestParam.getCollectionName(), e.getMessage());
+            return R.failed(e);
+        } catch (Exception e) {
+            logError("Search failed! Collection name:{}\n{}",
+                    requestParam.getCollectionName(), e.getMessage());
+            return R.failed(e);
+        }
+    }
+
     ///////////////////// Log Functions//////////////////////
     private void logDebug(String msg, Object... params) {
         logger.debug(msg, params);

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

@@ -26,9 +26,14 @@ import io.milvus.param.RpcStatus;
 import io.milvus.param.alias.*;
 import io.milvus.param.bulkinsert.*;
 import io.milvus.param.collection.*;
+import io.milvus.param.highlevel.collection.response.ListCollectionsResponse;
 import io.milvus.param.control.*;
 import io.milvus.param.credential.*;
 import io.milvus.param.dml.*;
+import io.milvus.param.highlevel.collection.CreateSimpleCollectionParam;
+import io.milvus.param.highlevel.collection.ListCollectionsParam;
+import io.milvus.param.highlevel.dml.*;
+import io.milvus.param.highlevel.dml.response.*;
 import io.milvus.param.index.*;
 import io.milvus.param.partition.*;
 import io.milvus.param.role.*;
@@ -634,4 +639,65 @@ public interface MilvusClient {
      * @return {status:result code, data:GetLoadStateResponse{status}}
      */
     R<GetLoadStateResponse> getLoadState(GetLoadStateParam requestParam);
+
+
+
+    ///////////////////// High Level API//////////////////////
+    /**
+     * Creates a collection in Milvus.
+     *
+     * @param requestParam {@link CreateSimpleCollectionParam}
+     * @return {status:result code, data:RpcStatus{msg: result message}}
+     */
+    R<RpcStatus> createCollection(CreateSimpleCollectionParam requestParam);
+
+    /**
+     * Lists all collections
+     *
+     * @param requestParam {@link ListCollectionsParam}
+     * @return {status:result code, data: ListCollectionsResponse{collection_names}}
+     */
+    R<ListCollectionsResponse> listCollections(ListCollectionsParam requestParam);
+
+    /**
+     * Inserts rows data into a specified collection . Note that you don't need to
+     * input primary key field if auto_id is enabled.
+     *
+     * @param requestParam {@link InsertRowsParam}
+     * @return {status:result code, data: MutationResult{insert results}}
+     */
+    R<InsertResponse> insert(InsertRowsParam requestParam);
+
+    /**
+     * Deletes entity(s) based on the value of primary key.
+     *
+     * @param requestParam {@link DeleteIdsParam}
+     * @return {status:result code, data: MutationResult{delete results}}
+     */
+    R<DeleteResponse> delete(DeleteIdsParam requestParam);
+
+    /**
+     * Get entity(s) based on the value of primary key.
+     *
+     * @param requestParam {@link GetIdsParam}
+     * @return {status:result code, data: QueryResults{query results}}
+     */
+    R<GetResponse> get(GetIdsParam requestParam);
+
+    /**
+     * Queries entity(s) based on scalar field(s) filtered by boolean expression.
+     * Note that the order of the returned entities cannot be guaranteed.
+     *
+     * @param requestParam {@link QuerySimpleParam}
+     * @return {status:result code,data: QueryResults{filter results}}
+     */
+    R<QueryResponse> query(QuerySimpleParam requestParam);
+
+    /**
+     * Conducts ANN search on a vector field. Use expression to do filtering before search.
+     *
+     * @param requestParam {@link SearchSimpleParam}
+     * @return {status:result code, data: SearchResults{topK results}}
+     */
+    R<SearchResponse> search(SearchSimpleParam requestParam);
 }

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

@@ -31,9 +31,14 @@ import io.milvus.param.ServerAddress;
 import io.milvus.param.alias.*;
 import io.milvus.param.bulkinsert.*;
 import io.milvus.param.collection.*;
+import io.milvus.param.highlevel.collection.response.ListCollectionsResponse;
 import io.milvus.param.control.*;
 import io.milvus.param.credential.*;
 import io.milvus.param.dml.*;
+import io.milvus.param.highlevel.collection.CreateSimpleCollectionParam;
+import io.milvus.param.highlevel.collection.ListCollectionsParam;
+import io.milvus.param.highlevel.dml.*;
+import io.milvus.param.highlevel.dml.response.*;
 import io.milvus.param.index.*;
 import io.milvus.param.partition.*;
 import io.milvus.param.role.*;
@@ -534,6 +539,53 @@ public class MilvusMultiServiceClient implements MilvusClient {
         return this.clusterFactory.getMaster().getClient().getLoadState(requestParam);
     }
 
+    ///////////////////// High Level API//////////////////////
+
+
+    @Override
+    public R<RpcStatus> createCollection(CreateSimpleCollectionParam requestParam) {
+        List<R<RpcStatus>> response = this.clusterFactory.getAvailableServerSettings().parallelStream()
+                .map(serverSetting -> serverSetting.getClient().createCollection(requestParam))
+                .collect(Collectors.toList());
+        return handleResponse(response);
+    }
+
+    @Override
+    public R<ListCollectionsResponse> listCollections(ListCollectionsParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().listCollections(requestParam);
+    }
+
+    @Override
+    public R<InsertResponse> insert(InsertRowsParam requestParam) {
+        List<R<InsertResponse>> response = this.clusterFactory.getAvailableServerSettings().parallelStream()
+                .map(serverSetting -> serverSetting.getClient().insert(requestParam))
+                .collect(Collectors.toList());
+        return handleResponse(response);
+    }
+
+    @Override
+    public R<DeleteResponse> delete(DeleteIdsParam requestParam) {
+        List<R<DeleteResponse>> response = this.clusterFactory.getAvailableServerSettings().stream()
+                .map(serverSetting -> serverSetting.getClient().delete(requestParam))
+                .collect(Collectors.toList());
+        return handleResponse(response);
+    }
+
+    @Override
+    public R<GetResponse> get(GetIdsParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().get(requestParam);
+    }
+
+    @Override
+    public R<QueryResponse> query(QuerySimpleParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().query(requestParam);
+    }
+
+    @Override
+    public R<SearchResponse> search(SearchSimpleParam requestParam) {
+        return this.clusterFactory.getMaster().getClient().search(requestParam);
+    }
+
     private <T> R<T> handleResponse(List<R<T>> response) {
         if (CollectionUtils.isNotEmpty(response)) {
             R<T> rSuccess = null;

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

@@ -24,6 +24,8 @@ import io.grpc.stub.MetadataUtils;
 import io.milvus.grpc.MilvusServiceGrpc;
 import io.milvus.param.ConnectParam;
 
+import io.milvus.param.R;
+import io.milvus.param.RpcStatus;
 import lombok.NonNull;
 import org.apache.commons.lang3.StringUtils;
 

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

@@ -0,0 +1,36 @@
+package io.milvus.common.utils;
+
+import io.milvus.exception.ParamException;
+import io.milvus.param.collection.FieldType;
+import io.milvus.response.DescCollResponseWrapper;
+import org.apache.logging.log4j.util.Strings;
+
+import java.util.List;
+import java.util.Optional;
+import java.util.stream.Collectors;
+
+public class VectorUtils {
+    public static String convertPksExpr(List<?> primaryIds, DescCollResponseWrapper wrapper) {
+        Optional<FieldType> optional = wrapper.getFields().stream().filter(FieldType::isPrimaryKey).findFirst();
+        String expr;
+        if (optional.isPresent()) {
+            FieldType primaryField = optional.get();
+            switch (primaryField.getDataType()) {
+                case Int64:
+                case VarChar:
+                    List<String> primaryStringIds = primaryIds.stream().map(String::valueOf).collect(Collectors.toList());
+                    expr = convertPksExpr(primaryStringIds, primaryField.getName());
+                    break;
+                default:
+                    throw new ParamException("The primary key is not of type int64 or varchar, and the current operation is not supported.");
+            }
+        } else {
+            throw new ParamException("No primary key found.");
+        }
+        return expr;
+    }
+
+    public static String convertPksExpr(List<?> primaryIds, String primaryFieldName) {
+        return primaryFieldName + " in [" + Strings.join(primaryIds, ',') + "]";
+    }
+}

+ 10 - 0
src/main/java/io/milvus/param/Constant.java

@@ -71,4 +71,14 @@ public class Constant {
     // set this value for "withGuaranteeTimestamp" of QueryParam/SearchParam
     // to instruct server execute query/search after all DML operations finished.
     public static final Long GUARANTEE_STRONG_TS = 0L;
+
+    // high level api
+    public static final String VECTOR_FIELD_NAME_DEFAULT  = "vector";
+    public static final String PRIMARY_FIELD_NAME_DEFAULT = "id";
+    public static final int SHARD_NUMBER_DEFAULT = 2;
+    public static final String VECTOR_INDEX_NAME_DEFAULT  = "vector_idx";
+    public static final Long LIMIT_DEFAULT = 100L;
+    public static final Long OFFSET_DEFAULT = 0L;
+    public static final String ALL_OUTPUT_FIELDS = "*";
+
 }

+ 13 - 0
src/main/java/io/milvus/param/ParamUtils.java

@@ -172,6 +172,19 @@ public class ParamUtils {
         }
     }
 
+    /**
+     * Checks if a string is  null.
+     * Throws {@link ParamException} if the string is null.
+     *
+     * @param target target string
+     * @param name a name to describe this string
+     */
+    public static void CheckNullString(String target, String name) throws ParamException {
+        if (target == null) {
+            throw new ParamException(name + " cannot be null");
+        }
+    }
+
     /**
      * Checks if a metric is for float vector.
      *

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

@@ -72,7 +72,7 @@ public class UpdateCredentialParam {
          */
         public UpdateCredentialParam build() throws ParamException {
             ParamUtils.CheckNullEmptyString(username, "Username");
-            ParamUtils.CheckNullEmptyString(oldPassword, "OldPassword");
+            ParamUtils.CheckNullString(oldPassword, "OldPassword");
             ParamUtils.CheckNullEmptyString(newPassword, "NewPassword");
 
             return new UpdateCredentialParam(this);

+ 9 - 2
src/main/java/io/milvus/param/dml/InsertParam.java

@@ -106,9 +106,9 @@ public class InsertParam {
         }
 
         /**
-         * Sets the data to insert. The field list cannot be empty.
+         * Sets the column data to insert. The field list cannot be empty.
          *
-         * @param fields insert data
+         * @param fields insert column data
          * @return <code>Builder</code>
          * @see InsertParam.Field
          */
@@ -117,6 +117,13 @@ public class InsertParam {
             return this;
         }
 
+        /**
+         * Sets the row data to insert. The rows list cannot be empty.
+         *
+         * @param rows insert row data
+         * @return <code>Builder</code>
+         * @see JSONObject
+         */
         public Builder withRows(@NonNull List<JSONObject> rows) {
             this.rows = rows;
             return this;

+ 1 - 1
src/main/java/io/milvus/param/dml/SearchParam.java

@@ -372,7 +372,7 @@ public class SearchParam {
                     throw new ParamException("Target vector is binary but metric type is incorrect");
                 }
             } else {
-                throw new ParamException("Target vector type must be Lst<Float> or ByteBuffer");
+                throw new ParamException("Target vector type must be List<Float> or ByteBuffer");
             }
 
             return new SearchParam(this);

+ 212 - 0
src/main/java/io/milvus/param/highlevel/collection/CreateSimpleCollectionParam.java

@@ -0,0 +1,212 @@
+/*
+ * 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.highlevel.collection;
+
+import com.google.common.collect.Lists;
+import io.milvus.common.clientenum.ConsistencyLevelEnum;
+import io.milvus.exception.ParamException;
+import io.milvus.grpc.DataType;
+import io.milvus.param.Constant;
+import io.milvus.param.IndexType;
+import io.milvus.param.MetricType;
+import io.milvus.param.ParamUtils;
+import io.milvus.param.collection.CreateCollectionParam;
+import io.milvus.param.collection.FieldType;
+import io.milvus.param.collection.LoadCollectionParam;
+import io.milvus.param.index.CreateIndexParam;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
+import org.apache.commons.lang3.StringUtils;
+import org.apache.logging.log4j.util.Strings;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Parameters for <code>createCollection</code> interface.
+ */
+@Getter
+@ToString
+public class CreateSimpleCollectionParam {
+    private final CreateCollectionParam createCollectionParam;
+    private final CreateIndexParam createIndexParam;
+    private final LoadCollectionParam loadCollectionParam;
+
+    private CreateSimpleCollectionParam(CreateCollectionParam createCollectionParam, CreateIndexParam createIndexParam, LoadCollectionParam loadCollectionParam) {
+        this.createCollectionParam = createCollectionParam;
+        this.createIndexParam = createIndexParam;
+        this.loadCollectionParam = loadCollectionParam;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link CreateSimpleCollectionParam} class.
+     */
+    public static final class Builder {
+        private String collectionName;
+        private int dimension;
+        private MetricType metricType = MetricType.L2;
+        private String description = Strings.EMPTY;
+        private String primaryField;
+        private String vectorField;
+        private boolean autoId = Boolean.FALSE;
+        private boolean syncLoad = Boolean.TRUE;
+
+        private Builder() {
+        }
+
+        /**
+         * 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 the collection vector dimension. Dimension value must be greater than zero and less than 32768.
+         *
+         * @param dimension collection vector dimension
+         * @return <code>Builder</code>
+         */
+        public Builder withDimension(int dimension) {
+            this.dimension = dimension;
+            return this;
+        }
+
+        /**
+         * Sets the metricType of vectorField. The distance metric used for the collection.
+         *
+         * @param metricType metricType of vectorField
+         * @return <code>Builder</code>
+         */
+        public Builder withMetricType(@NonNull MetricType metricType) {
+            this.metricType = metricType;
+            return this;
+        }
+
+        /**
+         * Sets the collection description. The description can be empty. The default is "".
+         *
+         * @param description description of the collection
+         * @return <code>Builder</code>
+         */
+        public Builder withDescription(@NonNull String description) {
+            this.description = description;
+            return this;
+        }
+
+        /**
+         * Sets the primaryFiled name. The primaryField cannot be empty or null. The default is "id".
+         *
+         * @param primaryField primaryFiled name of the collection
+         * @return <code>Builder</code>
+         */
+        public Builder withPrimaryField(@NonNull String primaryField) {
+            this.primaryField = primaryField;
+            return this;
+        }
+
+        /**
+         * Sets the vectorField name. The vectorField cannot be empty or null. The default is "vector".
+         *
+         * @param vectorField vectorField name of the collection
+         * @return <code>Builder</code>
+         */
+        public Builder withVectorField(@NonNull String vectorField) {
+            this.vectorField = vectorField;
+            return this;
+        }
+
+        /**
+         * Sets the autoId. The vectorField cannot be null. The default is Boolean.False.
+         *
+         * @param autoId if open autoId
+         * @return <code>Builder</code>
+         */
+        public Builder withAutoId(boolean autoId) {
+            this.autoId = autoId;
+            return this;
+        }
+
+        /**
+         * Sets the SyncLoad when loadCollection
+         */
+        public Builder withSyncLoad(boolean syncLoad) {
+            this.syncLoad = syncLoad;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link CreateSimpleCollectionParam} instance.
+         *
+         * @return {@link CreateSimpleCollectionParam}
+         */
+        public CreateSimpleCollectionParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(collectionName, "Collection name");
+            if (dimension <= 0) {
+                throw new ParamException("Dimension must be larger than 0");
+            }
+
+
+            String primaryFieldName = StringUtils.defaultIfEmpty(primaryField, Constant.PRIMARY_FIELD_NAME_DEFAULT);
+            String vectorFieldName = StringUtils.defaultString(vectorField, Constant.VECTOR_FIELD_NAME_DEFAULT);
+
+            Map<String, String> typeParams = new HashMap<>();
+            typeParams.put(Constant.VECTOR_DIM, String.valueOf(dimension));
+            List<FieldType> fieldTypes = Lists.newArrayList(
+                    FieldType.newBuilder().withName(primaryFieldName).withDataType(DataType.Int64).withPrimaryKey(Boolean.TRUE).withAutoID(autoId).build(),
+                    FieldType.newBuilder().withName(vectorFieldName).withDataType(DataType.FloatVector).withTypeParams(typeParams).build()
+            );
+            CreateCollectionParam createCollectionParam = CreateCollectionParam.newBuilder()
+                    .withCollectionName(collectionName)
+                    .withShardsNum(Constant.SHARD_NUMBER_DEFAULT)
+                    .withDescription(description)
+                    .withFieldTypes(fieldTypes)
+                    .withConsistencyLevel(ConsistencyLevelEnum.BOUNDED)
+                    .withEnableDynamicField(Boolean.TRUE)
+                    .build();
+
+            CreateIndexParam createIndexParam = CreateIndexParam.newBuilder()
+                    .withCollectionName(collectionName)
+                    .withFieldName(vectorFieldName)
+                    .withIndexName(Constant.VECTOR_INDEX_NAME_DEFAULT)
+                    .withMetricType(metricType)
+                    .withIndexType(IndexType.AUTOINDEX)
+                    .build();
+
+            LoadCollectionParam loadCollectionParam = LoadCollectionParam.newBuilder()
+                    .withCollectionName(collectionName)
+                    .withSyncLoad(syncLoad)
+                    .build();
+
+            return new CreateSimpleCollectionParam(createCollectionParam, createIndexParam, loadCollectionParam);
+        }
+    }
+}

+ 63 - 0
src/main/java/io/milvus/param/highlevel/collection/ListCollectionsParam.java

@@ -0,0 +1,63 @@
+/*
+ * 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.highlevel.collection;
+
+import io.milvus.exception.ParamException;
+import io.milvus.grpc.ShowType;
+import io.milvus.param.collection.ShowCollectionsParam;
+import lombok.Getter;
+import lombok.ToString;
+
+/**
+ * Parameters for <code>listCollections</code> interface.
+ */
+@Getter
+@ToString
+public class ListCollectionsParam {
+    private final ShowCollectionsParam showCollectionsParam;
+
+    private ListCollectionsParam(ShowCollectionsParam showCollectionsParam) {
+        this.showCollectionsParam = showCollectionsParam;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link ListCollectionsParam} class.
+     */
+    public static final class Builder {
+        private Builder() {
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link ListCollectionsParam} instance.
+         *
+         * @return {@link ListCollectionsParam}
+         */
+        public ListCollectionsParam build() throws ParamException {
+            ShowCollectionsParam showCollectionsParam = ShowCollectionsParam.newBuilder()
+                    .withShowType(ShowType.All)
+                    .build();
+            return new ListCollectionsParam(showCollectionsParam);
+        }
+    }
+}

+ 34 - 0
src/main/java/io/milvus/param/highlevel/collection/response/ListCollectionsResponse.java

@@ -0,0 +1,34 @@
+/*
+ * 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.highlevel.collection.response;
+
+import lombok.Builder;
+import lombok.ToString;
+
+import java.util.List;
+
+/**
+ * Parameters for <code>showCollections</code> interface.
+ */
+@Builder
+@ToString
+public class ListCollectionsResponse {
+    public List<String> collectionNames;
+}

+ 108 - 0
src/main/java/io/milvus/param/highlevel/dml/DeleteIdsParam.java

@@ -0,0 +1,108 @@
+/*
+ * 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.highlevel.dml;
+
+import io.milvus.exception.ParamException;
+import io.milvus.param.ParamUtils;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
+import org.apache.commons.collections4.CollectionUtils;
+import org.apache.logging.log4j.util.Strings;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Parameters for <code>delete</code> interface.
+ */
+@Getter
+@ToString
+public class DeleteIdsParam {
+
+    private final String collectionName;
+    private final List<?> primaryIds;
+
+    private DeleteIdsParam(@NonNull Builder builder) {
+        this.collectionName = builder.collectionName;
+        this.primaryIds = builder.primaryIds;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link DeleteIdsParam} class.
+     */
+    public static class Builder<T> {
+        private String collectionName;
+        private List<T> primaryIds = new ArrayList<>();
+
+        private Builder() {
+        }
+
+        /**
+         * 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;
+        }
+
+        /**
+         * Specifies primaryId fields. PrimaryIds cannot be empty or null.
+         *
+         * @param primaryIds input primary key list
+         * @return <code>Builder</code>
+         */
+        public Builder withPrimaryIds(@NonNull List<T> primaryIds) {
+            this.primaryIds.addAll(primaryIds);
+            return this;
+        }
+
+        /**
+         * Specifies primaryId field. PrimaryId cannot be empty or null.
+         *
+         * @param primaryId input primary key id
+         * @return <code>Builder</code>
+         */
+        public Builder addPrimaryId(@NonNull T primaryId) {
+            this.primaryIds.add(primaryId);
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link DeleteIdsParam} instance.
+         *
+         * @return {@link DeleteIdsParam}
+         */
+        public DeleteIdsParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(collectionName, "Collection name");
+            if (CollectionUtils.isEmpty(primaryIds)) {
+                throw new ParamException("PrimaryIds cannot be empty");
+            }
+            return new DeleteIdsParam(this);
+        }
+    }
+}

+ 122 - 0
src/main/java/io/milvus/param/highlevel/dml/GetIdsParam.java

@@ -0,0 +1,122 @@
+/*
+ * 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.highlevel.dml;
+
+import com.google.common.collect.Lists;
+import io.milvus.exception.ParamException;
+import io.milvus.param.ParamUtils;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
+import org.apache.commons.collections4.CollectionUtils;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Parameters for <code>get</code> interface.
+ */
+@Getter
+@ToString
+public class GetIdsParam {
+    private final String collectionName;
+    private final List<?> primaryIds;
+    private final List<String> outputFields;
+
+    private GetIdsParam(@NonNull Builder builder) {
+        this.collectionName = builder.collectionName;
+        this.primaryIds = builder.primaryIds;
+        this.outputFields = builder.outputFields;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link GetIdsParam} class.
+     */
+    public static class Builder<T> {
+        private String collectionName;
+        private List<T> primaryIds = new ArrayList<>();
+        private final List<String> outputFields = Lists.newArrayList();
+
+        private Builder() {
+        }
+
+        /**
+         * 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;
+        }
+
+        /**
+         * Specifies output fields (Optional).
+         *
+         * @param outputFields output fields
+         * @return <code>Builder</code>
+         */
+        public Builder withOutputFields(@NonNull List<String> outputFields) {
+            this.outputFields.addAll(outputFields);
+            return this;
+        }
+
+        /**
+         * Specifies primaryIds fields. PrimaryIds cannot be empty or null.
+         *
+         * @param primaryIds input primary key list
+         * @return <code>Builder</code>
+         */
+        public Builder withPrimaryIds(@NonNull List<T> primaryIds) {
+            this.primaryIds.addAll(primaryIds);
+            return this;
+        }
+
+        /**
+         * Specifies primaryId field. PrimaryId cannot be empty or null.
+         *
+         * @param primaryId input primary key id
+         * @return <code>Builder</code>
+         */
+        public Builder addPrimaryId(@NonNull T primaryId) {
+            this.primaryIds.add(primaryId);
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link GetIdsParam} instance.
+         *
+         * @return {@link GetIdsParam}
+         */
+        public GetIdsParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(collectionName, "Collection name");
+            if (CollectionUtils.isEmpty(primaryIds)) {
+                throw new ParamException("PrimaryIds cannot be empty");
+            }
+
+            return new GetIdsParam(this);
+        }
+    }
+}

+ 103 - 0
src/main/java/io/milvus/param/highlevel/dml/InsertRowsParam.java

@@ -0,0 +1,103 @@
+/*
+ * 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.highlevel.dml;
+
+import com.alibaba.fastjson.JSONObject;
+import io.milvus.exception.ParamException;
+import io.milvus.param.ParamUtils;
+import io.milvus.param.dml.InsertParam;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
+import org.apache.commons.collections4.CollectionUtils;
+
+import java.util.List;
+
+/**
+ * Parameters for <code>insert</code> interface.
+ */
+@Getter
+@ToString
+public class InsertRowsParam {
+
+    private final InsertParam insertParam;
+    private InsertRowsParam(InsertParam insertParam) {
+        this.insertParam = insertParam;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link InsertRowsParam} class.
+     */
+    public static class Builder {
+        private String collectionName;
+        private List<JSONObject> rows;
+
+        private Builder() {
+        }
+
+
+        /**
+         * 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 the row data to insert. The rows list cannot be empty.
+         *
+         * @param rows insert row data
+         * @return <code>Builder</code>
+         * @see JSONObject
+         */
+        public Builder withRows(@NonNull List<JSONObject> rows) {
+            this.rows = rows;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link InsertRowsParam} instance.
+         *
+         * @return {@link InsertRowsParam}
+         */
+        public InsertRowsParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(collectionName, "Collection name");
+
+            if (CollectionUtils.isEmpty(rows)) {
+                throw new ParamException("Rows cannot be empty");
+            }
+
+            // this method doesn't check data type, the insert() api will do this work
+            InsertParam insertParam = InsertParam.newBuilder()
+                    .withCollectionName(collectionName)
+                    .withRows(rows)
+                    .build();
+            return new InsertRowsParam(insertParam);
+        }
+    }
+}

+ 147 - 0
src/main/java/io/milvus/param/highlevel/dml/QuerySimpleParam.java

@@ -0,0 +1,147 @@
+/*
+ * 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.highlevel.dml;
+
+import io.milvus.exception.ParamException;
+import io.milvus.param.ParamUtils;
+import io.milvus.param.dml.QueryParam;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Parameters for <code>query</code> interface.
+ */
+@Getter
+@ToString
+public class QuerySimpleParam {
+    private final String collectionName;
+    private final List<String> outputFields;
+    private final String filter;
+    private final Long offset;
+    private final Long limit;
+
+    private QuerySimpleParam(@NotNull Builder builder) {
+        this.collectionName = builder.collectionName;
+        this.outputFields = builder.outputFields;
+        this.filter = builder.filter;
+        this.offset = builder.offset;
+        this.limit = builder.limit;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link QuerySimpleParam} class.
+     */
+    public static class Builder {
+        private String collectionName;
+        private final List<String> outputFields = new ArrayList<>();
+        private String filter = "";
+        private Long offset;
+        private Long limit;
+
+        private Builder() {
+        }
+
+        /**
+         * 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;
+        }
+
+        /**
+         * Specifies output fields (Optional).
+         *
+         * @param outFields output fields
+         * @return <code>Builder</code>
+         */
+        public Builder withOutFields(@NonNull List<String> outFields) {
+            this.outputFields.addAll(outFields);
+            return this;
+        }
+
+        /**
+         * Sets the expression to query entities.
+         * @see <a href="https://milvus.io/docs/v2.0.0/boolean.md">Boolean Expression Rules</a>
+         *
+         * @param filter filtering expression
+         * @return <code>Builder</code>
+         */
+        public Builder withFilter(@NonNull String filter) {
+            this.filter = filter;
+            return this;
+        }
+
+        /**
+         * Specify a position to return results. Only take effect when the 'limit' value is specified.
+         * Default value is 0, start from begin.
+         *
+         * @param offset a value to define the position
+         * @return <code>Builder</code>
+         */
+        public Builder withOffset(@NonNull Long offset) {
+            this.offset = offset;
+            return this;
+        }
+
+        /**
+         * Specify a value to control the returned number of entities. Must be a positive value.
+         * Default value is 0, will return without limit.
+         *
+         * @param limit a value to define the limit of returned entities
+         * @return <code>Builder</code>
+         */
+        public Builder withLimit(@NonNull Long limit) {
+            this.limit = limit;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link QuerySimpleParam} instance.
+         *
+         * @return {@link QuerySimpleParam}
+         */
+        public QuerySimpleParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(collectionName, "Collection name");
+            ParamUtils.CheckNullEmptyString(filter, "Filter");
+
+            if (offset < 0) {
+                throw new ParamException("The offset value cannot be less than 0");
+            }
+
+            if (limit < 0) {
+                throw new ParamException("The limit value cannot be less than 0");
+            }
+            return new QuerySimpleParam(this);
+        }
+    }
+}

+ 175 - 0
src/main/java/io/milvus/param/highlevel/dml/SearchSimpleParam.java

@@ -0,0 +1,175 @@
+/*
+ * 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.highlevel.dml;
+
+import com.google.common.collect.Lists;
+import io.milvus.exception.ParamException;
+import io.milvus.param.Constant;
+import io.milvus.param.ParamUtils;
+import lombok.Getter;
+import lombok.NonNull;
+import lombok.ToString;
+import org.apache.commons.collections4.CollectionUtils;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Parameters for <code>search</code> interface.
+ */
+@Getter
+@ToString
+public class SearchSimpleParam {
+    private final String collectionName;
+    private final List<?> vectors;
+    private final List<String> outputFields;
+    private final String filter;
+    private final Long offset;
+    private final int limit;
+
+    private final Map<String, Object> params;
+
+    private SearchSimpleParam(@NotNull Builder builder) {
+        this.collectionName = builder.collectionName;
+        this.vectors = builder.vectors;
+        this.outputFields = builder.outputFields;
+        this.filter = builder.filter;
+        this.offset = builder.offset;
+        this.limit = builder.limit;
+        this.params = builder.params;
+    }
+
+    public static Builder newBuilder() {
+        return new Builder();
+    }
+
+    /**
+     * Builder for {@link SearchSimpleParam} class.
+     */
+    public static class Builder {
+        private String collectionName;
+        private List<?> vectors;
+        private final List<String> outputFields = Lists.newArrayList();
+        private String filter = "";
+        private Long offset;
+        private int limit;
+
+        private final Map<String, Object> params = new HashMap<>();
+
+        Builder() {
+        }
+
+        /**
+         * 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 expression to filter out entities before searching (Optional).
+         *
+         * @param filter filtering expression
+         * @return <code>Builder</code>
+         * @see <a href="https://milvus.io/docs/v2.0.0/boolean.md">Boolean Expression Rules</a>
+         */
+        public Builder withFilter(@NonNull String filter) {
+            this.filter = filter;
+            return this;
+        }
+
+        /**
+         * Specifies output fields (Optional).
+         *
+         * @param outputFields output fields
+         * @return <code>Builder</code>
+         */
+        public Builder withOutputFields(@NonNull List<String> outputFields) {
+            this.outputFields.addAll(outputFields);
+            return this;
+        }
+
+        /**
+         * Sets the target vectors.
+         *
+         * @param vectors list of target vectors:
+         *               if vector type is FloatVector, vectors is List of List Float;
+         *               if vector type is BinaryVector, vectors is List of ByteBuffer;
+         * @return <code>Builder</code>
+         */
+        public Builder withVectors(@NonNull List<?> vectors) {
+            this.vectors = vectors;
+            return this;
+        }
+
+        /**
+         * Specify a position to return results. Only take effect when the 'limit' value is specified.
+         * Default value is 0, start from begin.
+         *
+         * @param offset a value to define the position
+         * @return <code>Builder</code>
+         */
+        public Builder withOffset(@NonNull Long offset) {
+            this.offset = offset;
+            return this;
+        }
+
+        /**
+         * Specify a value to control the returned number of entities. Must be a positive value.
+         * Default value is 0, will return without limit.
+         *
+         * @param limit a value to define the limit of returned entities
+         * @return <code>Builder</code>
+         */
+        public Builder withLimit(int limit) {
+            this.limit = limit;
+            return this;
+        }
+
+        /**
+         * Verifies parameters and creates a new {@link SearchSimpleParam} instance.
+         *
+         * @return {@link SearchSimpleParam}
+         */
+        public SearchSimpleParam build() throws ParamException {
+            ParamUtils.CheckNullEmptyString(collectionName, "Collection name");
+            if (CollectionUtils.isEmpty(vectors)) {
+                throw new ParamException("vector cannot be empty");
+            }
+
+            if (offset < 0) {
+                throw new ParamException("The offset value cannot be less than 0");
+            }
+
+            if (limit < 0) {
+                throw new ParamException("The limit value cannot be less than 0");
+            }
+
+            params.put(Constant.OFFSET, offset);
+            return new SearchSimpleParam(this);
+        }
+    }
+}

+ 36 - 0
src/main/java/io/milvus/param/highlevel/dml/response/DeleteResponse.java

@@ -0,0 +1,36 @@
+/*
+ * 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.highlevel.dml.response;
+
+import lombok.Builder;
+import lombok.Getter;
+import lombok.ToString;
+
+import java.util.List;
+
+/**
+ * Parameters for <code>delete</code> interface.
+ */
+@Builder
+@Getter
+@ToString
+public class DeleteResponse {
+    public List<?> deleteIds;
+}

+ 35 - 0
src/main/java/io/milvus/param/highlevel/dml/response/GetResponse.java

@@ -0,0 +1,35 @@
+/*
+ * 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.highlevel.dml.response;
+
+import io.milvus.response.QueryResultsWrapper;
+import lombok.Builder;
+import lombok.Getter;
+
+import java.util.List;
+
+/**
+ * Parameters for <code>get</code> interface.
+ */
+@Builder
+@Getter
+public class GetResponse {
+    public List<QueryResultsWrapper.RowRecord> rowRecords;
+}

+ 35 - 0
src/main/java/io/milvus/param/highlevel/dml/response/InsertResponse.java

@@ -0,0 +1,35 @@
+/*
+ * 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.highlevel.dml.response;
+
+import lombok.Builder;
+import lombok.Getter;
+
+import java.util.List;
+
+/**
+ * Parameters for <code>insert</code> interface.
+ */
+@Builder
+@Getter
+public class InsertResponse {
+    private Long insertCount;
+    public List<?> insertIds;
+}

+ 35 - 0
src/main/java/io/milvus/param/highlevel/dml/response/QueryResponse.java

@@ -0,0 +1,35 @@
+/*
+ * 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.highlevel.dml.response;
+
+import io.milvus.response.QueryResultsWrapper;
+import lombok.Builder;
+import lombok.Getter;
+
+import java.util.List;
+
+/**
+ * Parameters for <code>query</code> interface.
+ */
+@Builder
+@Getter
+public class QueryResponse {
+    public List<QueryResultsWrapper.RowRecord> rowRecords;
+}

+ 35 - 0
src/main/java/io/milvus/param/highlevel/dml/response/SearchResponse.java

@@ -0,0 +1,35 @@
+/*
+ * 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.highlevel.dml.response;
+
+import io.milvus.response.QueryResultsWrapper;
+import lombok.Builder;
+import lombok.Getter;
+
+import java.util.List;
+
+/**
+ * Parameters for <code>search</code> interface.
+ */
+@Builder
+@Getter
+public class SearchResponse {
+    public List<QueryResultsWrapper.RowRecord> rowRecords;
+}

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

@@ -1,6 +1,8 @@
 package io.milvus.response;
 
+import io.milvus.exception.ParamException;
 import io.milvus.grpc.CollectionSchema;
+import io.milvus.grpc.DataType;
 import io.milvus.grpc.DescribeCollectionResponse;
 import io.milvus.grpc.FieldSchema;
 import io.milvus.param.ParamUtils;
@@ -147,6 +149,42 @@ public class DescCollResponseWrapper {
         return null;
     }
 
+    /**
+     * Get the primary key field.
+     * throw ParamException if the primary key field doesn't exist.
+     *
+     * @return {@link FieldType} schema of the primary key field
+     */
+    public FieldType getPrimaryField() {
+        CollectionSchema schema = response.getSchema();
+        for (int i = 0; i < schema.getFieldsCount(); ++i) {
+            FieldSchema field = schema.getFields(i);
+            if (field.getIsPrimaryKey()) {
+                return ParamUtils.ConvertField(field);
+            }
+        }
+
+        throw new ParamException("No primary key found.");
+    }
+
+    /**
+     * Get the vector key field.
+     * throw ParamException if the vector key field doesn't exist.
+     *
+     * @return {@link FieldType} schema of the vector key field
+     */
+    public FieldType getVectorField() {
+        CollectionSchema schema = response.getSchema();
+        for (int i = 0; i < schema.getFieldsCount(); ++i) {
+            FieldSchema field = schema.getFields(i);
+            if (field.getDataType() == DataType.FloatVector || field.getDataType() == DataType.BinaryVector) {
+                return ParamUtils.ConvertField(field);
+            }
+        }
+
+        throw new ParamException("No vector key found.");
+    }
+
     /**
      * Construct a <code>String</code> by {@link DescCollResponseWrapper} instance.
      *

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

@@ -55,6 +55,21 @@ public class MutationResultWrapper {
         }
     }
 
+    /**
+     * Gets the ID array from returned by insert interface.
+     *
+     * @return List of Ids, ID array returned by insert interface
+     */
+    public List<?> getInsertIDs() {
+        if (result.getIDs().hasIntId()) {
+            return result.getIDs().getIntId().getDataList();
+        } else if (result.getIDs().hasStrId()) {
+            return result.getIDs().getStrId().getDataList();
+        } else {
+            throw new ParamException("No found insertIds, please check your requests");
+        }
+    }
+
     /**
      * Gets the row count of the deleted entities. Currently, this value is always equal to input row count
      *

+ 31 - 71
src/main/java/io/milvus/response/QueryResultsWrapper.java

@@ -1,10 +1,10 @@
 package io.milvus.response;
 
 import com.alibaba.fastjson.JSONObject;
-import io.milvus.exception.IllegalResponseException;
 import io.milvus.exception.ParamException;
 import io.milvus.grpc.*;
 
+import io.milvus.response.basic.RowRecordWrapper;
 import lombok.Getter;
 import lombok.NonNull;
 
@@ -13,7 +13,7 @@ import java.util.*;
 /**
  * Utility class to wrap response of <code>query</code> interface.
  */
-public class QueryResultsWrapper {
+public class QueryResultsWrapper extends RowRecordWrapper {
     private final QueryResults results;
 
     public QueryResultsWrapper(@NonNull QueryResults results) {
@@ -39,26 +39,38 @@ public class QueryResultsWrapper {
     }
 
     /**
-     * Get the dynamic field. Only available when a collection's dynamic field is enabled.
-     * Throws {@link ParamException} if the dynamic field doesn't exist.
+     * Gets row records list from query result.
      *
-     * @return {@link FieldDataWrapper}
+     * @return <code>List<RowRecord></code> a row records list of the query result
      */
-    public FieldDataWrapper getDynamicWrapper() throws ParamException {
-        List<FieldData> fields = results.getFieldsDataList();
-        for (FieldData field : fields) {
-            if (field.getIsDynamic()) {
-                return new FieldDataWrapper(field);
-            }
+    @Override
+    public List<QueryResultsWrapper.RowRecord> getRowRecords() {
+        long rowCount = getRowCount();
+        List<QueryResultsWrapper.RowRecord> records = new ArrayList<>();
+        for (long i = 0; i < rowCount; i++) {
+            QueryResultsWrapper.RowRecord record = buildRowRecord(i);
+            records.add(record);
         }
 
-        throw new ParamException("The dynamic field doesn't exist");
+        return records;
     }
 
     /**
-     * Gets the row count of a query result.
+     * Gets a row record from result.
+     *  Throws {@link ParamException} if the index is illegal.
      *
-     * @return <code>long</code> row count of the query result
+     * @return <code>RowRecord</code> a row record of the result
+     */
+    protected QueryResultsWrapper.RowRecord buildRowRecord(long index) {
+        QueryResultsWrapper.RowRecord record = new QueryResultsWrapper.RowRecord();
+        buildRowRecord(record, index);
+        return record;
+    }
+
+    /**
+     * Gets the row count of the result.
+     *
+     * @return <code>long</code> row count of the result
      */
     public long getRowCount() {
         List<FieldData> fields = results.getFieldsDataList();
@@ -70,65 +82,13 @@ public class QueryResultsWrapper {
         return 0L;
     }
 
-    /**
-     * Gets a row record from query result.
-     *  Throws {@link ParamException} if the index is illegal.
-     *
-     * @return <code>RowRecord</code> a row record of the query result
-     */
-    public RowRecord getRowRecord(long index) throws ParamException {
-        List<String> outputFields = results.getOutputFieldsList();
-        List<FieldData> fields = results.getFieldsDataList();
-
-        RowRecord record = new RowRecord();
-        for (String outputKey : outputFields) {
-            boolean isField = false;
-            for (FieldData field : fields) {
-                if (outputKey.equals(field.getFieldName())) {
-                    FieldDataWrapper wrapper = new FieldDataWrapper(field);
-                    if (index < 0 || index >= wrapper.getRowCount()) {
-                        throw new ParamException("Index out of range");
-                    }
-                    Object value = wrapper.valueByIdx((int)index);
-                    if (wrapper.isJsonField()) {
-                        record.put(field.getFieldName(), JSONObject.parseObject(new String((byte[])value)));
-                    } else {
-                        record.put(field.getFieldName(), value);
-                    }
-                    isField = true;
-                    break;
-                }
-            }
-
-            // if the output field is not a field name, fetch it from dynamic field
-            if (!isField) {
-                FieldDataWrapper dynamicField = getDynamicWrapper();
-                if (dynamicField != null) {
-                    Object obj = dynamicField.get((int)index, outputKey);
-                    if (obj != null) {
-                        record.put(outputKey, obj);
-                    }
-                }
-            }
-        }
-
-        return record;
+    @Override
+    protected List<FieldData> getFieldDataList() {
+        return results.getFieldsDataList();
     }
 
-    /**
-     * Gets row records list from query result.
-     *
-     * @return <code>List<RowRecord></code> a row records list of the query result
-     */
-    public List<RowRecord> getRowRecords() {
-        long rowCount = getRowCount();
-        List<RowRecord> records = new ArrayList<>();
-        for (long i = 0; i < rowCount; i++) {
-            RowRecord record = getRowRecord(i);
-            records.add(record);
-        }
-
-        return records;
+    protected List<String> getOutputFields() {
+        return results.getOutputFieldsList();
     }
 
     /**

+ 39 - 1
src/main/java/io/milvus/response/SearchResultsWrapper.java

@@ -4,6 +4,7 @@ import com.alibaba.fastjson.JSONObject;
 import io.milvus.exception.IllegalResponseException;
 import io.milvus.exception.ParamException;
 import io.milvus.grpc.*;
+import io.milvus.response.basic.RowRecordWrapper;
 import lombok.Getter;
 import lombok.NonNull;
 
@@ -15,7 +16,7 @@ import java.util.Map;
 /**
  * Utility class to wrap response of <code>search</code> interface.
  */
-public class SearchResultsWrapper {
+public class SearchResultsWrapper extends RowRecordWrapper {
     private final SearchResultData results;
 
     public SearchResultsWrapper(@NonNull SearchResultData results) {
@@ -40,6 +41,43 @@ public class SearchResultsWrapper {
         throw new ParamException("The field name doesn't exist");
     }
 
+    @Override
+    public List<QueryResultsWrapper.RowRecord> getRowRecords() {
+        List<QueryResultsWrapper.RowRecord> records = new ArrayList<>();
+        long topK = results.getTopK();
+        for (int i = 0; i < topK; ++i) {
+            QueryResultsWrapper.RowRecord rowRecord = buildRowRecord(i);
+            records.add(rowRecord);
+        }
+        return records;
+    }
+
+    /**
+     * Gets a row record from result.
+     *  Throws {@link ParamException} if the index is illegal.
+     *
+     * @return <code>RowRecord</code> a row record of the result
+     */
+    protected QueryResultsWrapper.RowRecord buildRowRecord(long index) {
+        QueryResultsWrapper.RowRecord record = new QueryResultsWrapper.RowRecord();
+
+        List<IDScore> idScore = getIDScore(0);
+        record.put("id", idScore.get((int) index).getLongID());
+        record.put("distance", idScore.get((int)index).getScore());
+
+        buildRowRecord(record, index);
+        return record;
+    }
+
+    @Override
+    protected List<FieldData> getFieldDataList() {
+        return results.getFieldsDataList();
+    }
+
+    protected List<String> getOutputFields() {
+        return results.getOutputFieldsList();
+    }
+
     /**
      * Gets data for an output field which is specified by search request.
      * Throws {@link ParamException} if the field doesn't exist.

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

@@ -19,6 +19,10 @@ public class ShowCollResponseWrapper {
         this.response = response;
     }
 
+    public List<String> getCollectionNames() {
+        return response.getCollectionNamesList();
+    }
+
     /**
      * Get information of the collections.
      *

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

@@ -0,0 +1,81 @@
+package io.milvus.response.basic;
+
+import com.alibaba.fastjson.JSONObject;
+import io.milvus.exception.ParamException;
+import io.milvus.grpc.FieldData;
+import io.milvus.response.FieldDataWrapper;
+import io.milvus.response.QueryResultsWrapper;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class RowRecordWrapper {
+
+    public abstract List<QueryResultsWrapper.RowRecord> getRowRecords();
+
+    /**
+     * Get the dynamic field. Only available when a collection's dynamic field is enabled.
+     * Throws {@link ParamException} if the dynamic field doesn't exist.
+     *
+     * @return {@link FieldDataWrapper}
+     */
+    public FieldDataWrapper getDynamicWrapper() throws ParamException {
+        List<FieldData> fields = getFieldDataList();
+        for (FieldData field : fields) {
+            if (field.getIsDynamic()) {
+                return new FieldDataWrapper(field);
+            }
+        }
+
+        throw new ParamException("The dynamic field doesn't exist");
+    }
+
+    /**
+     * Gets a row record from result.
+     *  Throws {@link ParamException} if the index is illegal.
+     *
+     * @return <code>RowRecord</code> a row record of the result
+     */
+    protected QueryResultsWrapper.RowRecord buildRowRecord(QueryResultsWrapper.RowRecord record, long index) {
+        for (String outputKey : getOutputFields()) {
+            boolean isField = false;
+            for (FieldData field : getFieldDataList()) {
+                if (outputKey.equals(field.getFieldName())) {
+                    FieldDataWrapper wrapper = new FieldDataWrapper(field);
+                    if (index < 0 || index >= wrapper.getRowCount()) {
+                        throw new ParamException("Index out of range");
+                    }
+                    Object value = wrapper.valueByIdx((int)index);
+                    if (wrapper.isJsonField()) {
+                        JSONObject jsonField = JSONObject.parseObject(new String((byte[])value));
+                        if (wrapper.isDynamicField()) {
+                            for (String key: jsonField.keySet()) {
+                                record.put(key, jsonField.get(key));
+                            }
+                        } else {
+                            record.put(field.getFieldName(), jsonField);
+                        }
+                    } else {
+                        record.put(field.getFieldName(), value);
+                    }
+                    isField = true;
+                    break;
+                }
+            }
+
+            // if the output field is not a field name, fetch it from dynamic field
+            if (!isField) {
+                FieldDataWrapper dynamicField = getDynamicWrapper();
+                Object obj = dynamicField.get((int)index, outputKey);
+                if (obj != null) {
+                    record.put(outputKey, obj);
+                }
+            }
+        }
+        return record;
+    }
+
+    protected abstract List<FieldData> getFieldDataList();
+    protected abstract List<String> getOutputFields();
+
+}