syntax = "proto3";
package milvus.proto.milvus;

option go_package = "github.com/milvus-io/milvus/internal/proto/milvuspb";

import "common.proto";
import "schema.proto";

service MilvusService {
  rpc CreateCollection(CreateCollectionRequest) returns (common.Status) {}
  rpc DropCollection(DropCollectionRequest) returns (common.Status) {}
  rpc HasCollection(HasCollectionRequest) returns (BoolResponse) {}
  rpc LoadCollection(LoadCollectionRequest) returns (common.Status) {}
  rpc ReleaseCollection(ReleaseCollectionRequest) returns (common.Status) {}
  rpc DescribeCollection(DescribeCollectionRequest) returns (DescribeCollectionResponse) {}
  rpc GetCollectionStatistics(GetCollectionStatisticsRequest) returns (GetCollectionStatisticsResponse) {}
  rpc ShowCollections(ShowCollectionsRequest) returns (ShowCollectionsResponse) {}

  rpc CreatePartition(CreatePartitionRequest) returns (common.Status) {}
  rpc DropPartition(DropPartitionRequest) returns (common.Status) {}
  rpc HasPartition(HasPartitionRequest) returns (BoolResponse) {}
  rpc LoadPartitions(LoadPartitionsRequest) returns (common.Status) {}
  rpc ReleasePartitions(ReleasePartitionsRequest) returns (common.Status) {}
  rpc GetPartitionStatistics(GetPartitionStatisticsRequest) returns (GetPartitionStatisticsResponse) {}
  rpc ShowPartitions(ShowPartitionsRequest) returns (ShowPartitionsResponse) {}

  rpc CreateIndex(CreateIndexRequest) returns (common.Status) {}
  rpc DescribeIndex(DescribeIndexRequest) returns (DescribeIndexResponse) {}
  rpc GetIndexState(GetIndexStateRequest) returns (GetIndexStateResponse) {}
  rpc GetIndexBuildProgress(GetIndexBuildProgressRequest) returns (GetIndexBuildProgressResponse) {}
  rpc DropIndex(DropIndexRequest) returns (common.Status) {}

  rpc Insert(InsertRequest) returns (MutationResult) {}
  rpc Search(SearchRequest) returns (SearchResults) {}
  rpc Retrieve(RetrieveRequest) returns (RetrieveResults) {}
  rpc Flush(FlushRequest) returns (FlushResponse) {}
  rpc Query(QueryRequest) returns (QueryResults) {}
  rpc CalcDistance(CalcDistanceRequest) returns (CalcDistanceResults) {}

  rpc GetPersistentSegmentInfo(GetPersistentSegmentInfoRequest) returns (GetPersistentSegmentInfoResponse) {}
  rpc GetQuerySegmentInfo(GetQuerySegmentInfoRequest) returns (GetQuerySegmentInfoResponse) {}

  rpc Dummy(DummyRequest) returns (DummyResponse) {}

  // TODO: remove
  rpc RegisterLink(RegisterLinkRequest) returns (RegisterLinkResponse) {}
}

message CreateCollectionRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  // `schema` is the serialized `schema.CollectionSchema`
  bytes schema = 4; // must
  int32 shards_num = 5; // must. Once set, no modification is allowed
}

message DropCollectionRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
}

message HasCollectionRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  uint64 time_stamp = 4;
}

message BoolResponse {
  common.Status status = 1;
  bool value = 2;
}

message StringResponse {
  common.Status status = 1;
  string value = 2;
}

message DescribeCollectionRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  int64 collectionID = 4;
  uint64 time_stamp = 5;
}

message DescribeCollectionResponse {
  common.Status status = 1;
  schema.CollectionSchema schema = 2;
  int64 collectionID = 3;
  repeated string virtual_channel_names = 4;
  repeated string physical_channel_names = 5;
}

message LoadCollectionRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
}

message ReleaseCollectionRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
}

message GetCollectionStatisticsRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
}

message GetCollectionStatisticsResponse {
  common.Status status = 1;
  repeated common.KeyValuePair stats = 2;
}

enum ShowCollectionsType {
  All = 0;
  InMemory = 1;
}

message ShowCollectionsRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  uint64 time_stamp = 3;
  ShowCollectionsType type = 4;
}

message ShowCollectionsResponse {
  common.Status status = 1;
  repeated string collection_names = 2;
  repeated int64 collection_ids = 3;
}

message CreatePartitionRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  string partition_name = 4; // must
}

message DropPartitionRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  string partition_name = 4; // must
}

message HasPartitionRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  string partition_name = 4; // must
}

message LoadPartitionsRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  repeated string partition_names = 4; // must
}

message ReleasePartitionsRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  repeated string partition_names = 4; // must
}

message GetPartitionStatisticsRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  string partition_name = 4; // must
}

message GetPartitionStatisticsResponse {
  common.Status status = 1;
  repeated common.KeyValuePair stats = 2;
}

message ShowPartitionsRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  int64 collectionID = 4;
}

message ShowPartitionsResponse {
  common.Status status = 1;
  repeated string partition_names = 2;
  repeated int64 partitionIDs = 3;
}

message DescribeSegmentRequest {
  common.MsgBase base = 1;
  int64 collectionID = 2;
  int64 segmentID = 3;
}

message DescribeSegmentResponse {
  common.Status status = 1;
  int64 indexID = 2;
  int64 buildID = 3;
  bool enable_index = 4;
}

message ShowSegmentsRequest {
  common.MsgBase base = 1;
  int64 collectionID = 2;
  int64 partitionID = 3;
}

message ShowSegmentsResponse {
  common.Status status = 1;
  repeated int64 segmentIDs = 2;
}

message CreateIndexRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  string field_name = 4; // must
  repeated common.KeyValuePair extra_params = 5; // must
}

message DescribeIndexRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  string field_name = 4;
  string index_name = 5; // No need to set up for now @2021.06.30
}

message IndexDescription {
  string index_name = 1;
  int64 indexID = 2;
  repeated common.KeyValuePair params = 3;
  string field_name = 4;
}

message DescribeIndexResponse {
  common.Status status = 1;
  repeated IndexDescription index_descriptions = 2;
}

message GetIndexBuildProgressRequest {
  common.MsgBase base = 1; // must
  string db_name = 2 ;
  string collection_name = 3; // must
  string field_name = 4;
  string index_name = 5; // must
}

message GetIndexBuildProgressResponse {
  common.Status status = 1;
  int64 indexed_rows = 2;
  int64 total_rows = 3;
}

message GetIndexStateRequest {
  common.MsgBase base = 1; // must
  string db_name = 2 ;
  string collection_name = 3; // must
  string field_name = 4;
  string index_name = 5; // No need to set up for now @2021.06.30
}

message GetIndexStateResponse {
  common.Status status = 1;
  common.IndexState state = 2;
}

message DropIndexRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  string field_name = 4;
  string index_name = 5; // No need to set up for now @2021.06.30
}

message InsertRequest {
  common.MsgBase base = 1;
  string db_name = 2;
  string collection_name = 3;
  string partition_name = 4;
  repeated schema.FieldData fields_data = 5;
  repeated uint32 hash_keys = 6;
  uint32 num_rows = 7;
}

message MutationResult {
  common.Status status = 1;
  schema.IDs IDs = 2; // required for insert, delete
  repeated uint32 succ_index = 3; // error indexes indicate
  repeated uint32 err_index = 4; // error indexes indicate
  bool acknowledged = 5;
  int64 insert_cnt = 6;
  int64 delete_cnt = 7;
  int64 upsert_cnt = 8;
  uint64 timestamp = 9;
}

enum PlaceholderType {
  None = 0;
  BinaryVector = 100;
  FloatVector = 101;
}

message PlaceholderValue {
  string tag = 1;
  PlaceholderType type = 2;
  // values is a 2d-array, every array contains a vector
  repeated bytes values = 3;
}

message PlaceholderGroup {
  repeated PlaceholderValue placeholders = 1;
}

message SearchRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  repeated string partition_names = 4; // must
  string dsl = 5; // must
  // serialized `PlaceholderGroup`
  bytes placeholder_group = 6; // must
  common.DslType dsl_type = 7; // must
  repeated string output_fields = 8;
  repeated common.KeyValuePair search_params = 9; // must
  uint64 travel_timestamp = 10;
  uint64 guarantee_timestamp = 11; // guarantee_timestamp
}

message RetrieveRequest {
  common.MsgBase base = 1; // must
  string db_name = 2;
  string collection_name = 3; // must
  repeated string partition_names = 4; // must
  schema.IDs ids = 5; // must
  repeated string output_fields = 6; // must
  uint64 travel_timestamp = 7;
  uint64 guarantee_timestamp = 8; // guarantee_timestamp
}

message RetrieveResults {
  common.Status status = 1;
  schema.IDs ids = 2;
  repeated schema.FieldData fields_data = 3;
}

message Hits {
  repeated int64 IDs = 1;
  repeated bytes row_data = 2;
  repeated float scores = 3;
}

message SearchResults {
  common.Status status = 1;
  schema.SearchResultData results = 2;
}

message FlushRequest {
  common.MsgBase base = 1;
  string db_name = 2;
  repeated string collection_names = 3;
}

message FlushResponse{
  common.Status status = 1;
  string db_name = 2;
  map<string, schema.LongArray> coll_segIDs = 3;
}

message QueryRequest {
  common.MsgBase base = 1;
  string db_name = 2;
  string collection_name = 3;
  string expr = 4;
  repeated string output_fields = 5;
  repeated string partition_names = 6;
}

message QueryResults {
  common.Status status = 1;
  repeated schema.FieldData fields_data = 2;
}

message VectorIDs {
  string collection_name = 1;
  string field_name = 2;
  schema.IDs id_array = 3;
  repeated string partition_names = 4;
}

message VectorsArray {
  oneof array {
    VectorIDs id_array = 1; // vector ids
    schema.VectorField data_array = 2; // vectors data
  } 
}

message CalcDistanceRequest {
  common.MsgBase base = 1;
  VectorsArray op_left = 2; // vectors on the left of operator
  VectorsArray op_right = 3; // vectors on the right of operator
  repeated common.KeyValuePair params = 4; // "metric":"L2"/"IP"/"HAMMIN"/"TANIMOTO"
}

message CalcDistanceResults {
  common.Status status = 1;
  // num(op_left)*num(op_right) distance values, "HAMMIN" return integer distance
  oneof array {
    schema.IntArray int_dist = 2;
	schema.FloatArray float_dist = 3;
  }
}

message PersistentSegmentInfo {
  int64 segmentID = 1;
  int64 collectionID = 2;
  int64 partitionID = 3;
  int64 num_rows = 4;
  common.SegmentState state = 5;
}

message GetPersistentSegmentInfoRequest {
  common.MsgBase base = 1; // must
  string dbName = 2;
  string collectionName = 3; // must
}

message GetPersistentSegmentInfoResponse {
  common.Status status = 1;
  repeated PersistentSegmentInfo infos = 2;
}

message QuerySegmentInfo {
  int64 segmentID = 1;
  int64 collectionID = 2;
  int64 partitionID = 3;
  int64 mem_size = 4;
  int64 num_rows = 5;
  string index_name = 6;
  int64 indexID = 7;
}

message GetQuerySegmentInfoRequest {
  common.MsgBase base = 1; // must
  string dbName = 2;
  string collectionName = 3; // must
}

message GetQuerySegmentInfoResponse {
  common.Status status = 1;
  repeated QuerySegmentInfo infos = 2;
}

message DummyRequest {
  string request_type = 1;
}

message DummyResponse {
  string response = 1;
}

message RegisterLinkRequest {
}

message RegisterLinkResponse {
  common.Address address = 1;
  common.Status status = 2;
}

service ProxyService {
  rpc RegisterLink(RegisterLinkRequest) returns (RegisterLinkResponse) {}
}
