// Copyright 2026 Google LLC
//
// Licensed 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.

syntax = "proto3";

package google.cloud.vectorsearch.v1beta;

import "google/api/annotations.proto";
import "google/api/client.proto";
import "google/api/field_behavior.proto";
import "google/api/resource.proto";
import "google/cloud/vectorsearch/v1beta/common.proto";
import "google/cloud/vectorsearch/v1beta/data_object.proto";
import "google/cloud/vectorsearch/v1beta/embedding_config.proto";
import "google/protobuf/struct.proto";
import "google/rpc/status.proto";

option csharp_namespace = "Google.Cloud.VectorSearch.V1Beta";
option go_package = "cloud.google.com/go/vectorsearch/apiv1beta/vectorsearchpb;vectorsearchpb";
option java_multiple_files = true;
option java_outer_classname = "DataObjectSearchServiceProto";
option java_package = "com.google.cloud.vectorsearch.v1beta";
option php_namespace = "Google\\Cloud\\VectorSearch\\V1beta";
option ruby_package = "Google::Cloud::VectorSearch::V1beta";

// Service for searching data objects.
service DataObjectSearchService {
  option (google.api.default_host) = "vectorsearch.googleapis.com";
  option (google.api.oauth_scopes) =
      "https://www.googleapis.com/auth/cloud-platform";

  // Searches data objects.
  rpc SearchDataObjects(SearchDataObjectsRequest)
      returns (SearchDataObjectsResponse) {
    option (google.api.http) = {
      post: "/v1beta/{parent=projects/*/locations/*/collections/*}/dataObjects:search"
      body: "*"
    };
  }

  // Queries data objects.
  rpc QueryDataObjects(QueryDataObjectsRequest)
      returns (QueryDataObjectsResponse) {
    option (google.api.http) = {
      post: "/v1beta/{parent=projects/*/locations/*/collections/*}/dataObjects:query"
      body: "*"
    };
  }

  // Aggregates data objects.
  rpc AggregateDataObjects(AggregateDataObjectsRequest)
      returns (AggregateDataObjectsResponse) {
    option (google.api.http) = {
      post: "/v1beta/{parent=projects/*/locations/*/collections/*}/dataObjects:aggregate"
      body: "*"
    };
  }

  // Batch searches data objects.
  rpc BatchSearchDataObjects(BatchSearchDataObjectsRequest)
      returns (BatchSearchDataObjectsResponse) {
    option (google.api.http) = {
      post: "/v1beta/{parent=projects/*/locations/*/collections/*}/dataObjects:batchSearch"
      body: "*"
    };
  }
}

// Aggregation methods.
enum AggregationMethod {
  // Should not be used.
  AGGREGATION_METHOD_UNSPECIFIED = 0;

  // Count the number of data objects that match the filter.
  COUNT = 1;
}

// Defines a output fields struct for data in DataObject.
message OutputFields {
  // Optional. The fields from the data fields to include in the output.
  repeated string data_fields = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The fields from the vector fields to include in the output.
  repeated string vector_fields = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The fields from the DataObject metadata to include in the output.
  repeated string metadata_fields = 3 [(google.api.field_behavior) = OPTIONAL];
}

// Represents a hint to the search index engine.
message SearchHint {
  // Message to specify the index to use for the search.
  message IndexHint {
    // Parameters for dense ScaNN.
    message DenseScannParams {
      // Optional. Dense ANN param overrides to control recall and latency.
      // The percentage of leaves to search, in the range [0, 100].
      // Not supported for `STORAGE_OPTIMIZED` indexes.
      // Cannot be set together with `target_recall`.
      int32 search_leaves_pct = 1 [(google.api.field_behavior) = OPTIONAL];

      // Optional. The number of initial candidates. Must be a positive integer
      // (> 0). Not supported for `STORAGE_OPTIMIZED` indexes. Cannot be set
      // together with `target_recall`.
      int32 initial_candidate_count = 2
          [(google.api.field_behavior) = OPTIONAL];

      // Optional. The target recall for the search. Must be a double in the
      // range [0, 1]. While the search aims to achieve this level of recall, it
      // is not guaranteed.
      optional double target_recall = 3
          [(google.api.field_behavior) = OPTIONAL];
    }

    // The parameters for the index.
    oneof params {
      // Optional. Dense ScaNN parameters.
      DenseScannParams dense_scann_params = 2
          [(google.api.field_behavior) = OPTIONAL];
    }

    // Required. The resource name of the index to use for the search.
    // The index must be in the same project, location, and collection.
    // Format:
    // `projects/{project}/locations/{location}/collections/{collection}/indexes/{index}`
    string name = 1 [
      (google.api.field_behavior) = REQUIRED,
      (google.api.resource_reference) = {
        type: "vectorsearch.googleapis.com/Index"
      }
    ];
  }

  // KnnHint will be used if search should be explicitly done on system's
  // default K-Nearest Neighbor (KNN) index engine.
  message KnnHint {}

  // The type of index to use.
  oneof index_type {
    // Optional. Deprecated: Use `index_hint` instead.
    // Specifies that the search should use a particular index.
    IndexHint use_index = 1
        [deprecated = true, (google.api.field_behavior) = OPTIONAL];

    // Optional. Deprecated: Use `knn_hint` instead.
    // If set to true, the search will use the system's default
    // K-Nearest Neighbor (KNN) index engine.
    bool use_knn = 2
        [deprecated = true, (google.api.field_behavior) = OPTIONAL];

    // Optional. If set, the search will use the system's default
    // K-Nearest Neighbor (KNN) index engine.
    KnnHint knn_hint = 3 [(google.api.field_behavior) = OPTIONAL];

    // Optional. Specifies that the search should use a particular index.
    IndexHint index_hint = 4 [(google.api.field_behavior) = OPTIONAL];
  }
}

// A single search request within a batch operation.
message Search {
  // The type of search to perform.
  oneof search_type {
    // A vector-based search.
    VectorSearch vector_search = 1;

    // A semantic search.
    SemanticSearch semantic_search = 2;

    // A text search operation.
    TextSearch text_search = 3;
  }
}

// Defines a search operation using a query vector.
message VectorSearch {
  // Specifies the type of vector to use for the query.
  oneof vector_type {
    // A dense vector for the query.
    DenseVector vector = 1;

    // A sparse vector for the query.
    SparseVector sparse_vector = 2;
  }

  // Required. The vector field to search.
  string search_field = 8 [(google.api.field_behavior) = REQUIRED];

  // Optional. A JSON filter expression, e.g. {"genre": {"$eq": "sci-fi"}},
  // represented as a google.protobuf.Struct.
  google.protobuf.Struct filter = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The number of nearest neighbors to return.
  optional int32 top_k = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Mask specifying which fields to return.
  OutputFields output_fields = 7 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Sets the search hint. If no strategy is specified, the service
  // will use an index if one is available, and fall back to the default KNN
  // search otherwise.
  SearchHint search_hint = 9 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The distance metric to use for the KNN search. If not specified,
  // DOT_PRODUCT will be used as the default.
  DistanceMetric distance_metric = 11 [(google.api.field_behavior) = OPTIONAL];
}

// Defines a semantic search operation.
message SemanticSearch {
  // Optional. The query text, which is used to generate an embedding according
  // to the embedding model specified in the collection config.
  //
  // Required when using the text search mode.
  string search_text = 1 [(google.api.field_behavior) = OPTIONAL];

  // Required. The vector field to search.
  string search_field = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The task type of the query embedding. Must be specified for
  // text-only embedding models, see
  // <https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/embeddings/task-types>
  // Not needed for multi modal embedding models, see
  // <https://docs.cloud.google.com/gemini-enterprise-agent-platform/models/embeddings/get-multimodal-embeddings#specify-task-instructions>
  EmbeddingTaskType task_type = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The fields to return in the search results.
  OutputFields output_fields = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A JSON filter expression, e.g. {"genre": {"$eq": "sci-fi"}},
  // represented as a google.protobuf.Struct.
  google.protobuf.Struct filter = 6 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The number of data objects to return.
  optional int32 top_k = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Sets the search hint. If no strategy is specified, the service
  // will use an index if one is available, and fall back to KNN search
  // otherwise.
  SearchHint search_hint = 7 [(google.api.field_behavior) = OPTIONAL];
}

// Defines a text search operation.
message TextSearch {
  // Optional. The query text. Required when using the default text search mode.
  string search_text = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The data field names to search. Required when using the default
  // text search mode.
  repeated string data_field_names = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The fields to return in the search results.
  OutputFields output_fields = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The number of results to return.
  optional int32 top_k = 4 [(google.api.field_behavior) = OPTIONAL];

  // Optional. A JSON filter expression, e.g. `{"genre": {"$eq": "sci-fi"}}`,
  // represented as a `google.protobuf.Struct`.
  google.protobuf.Struct filter = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Structured query definition. When set, `search_text` and
  // `data_field_names` must be left empty; otherwise the request will be
  // rejected with an `INVALID_ARGUMENT` error. Conversely, when
  // `structured_query` is unset, both `search_text` and `data_field_names`
  // are required.
  StructuredQuery structured_query = 6 [(google.api.field_behavior) = OPTIONAL];
}

// A structured query for text search. Allows expressing field-targeted text
// queries combined via boolean operators, with optional per-node boosting.
message StructuredQuery {
  // The type of query to execute.
  oneof query_type {
    // Optional. A leaf-level text query.
    TextQuery text = 1 [(google.api.field_behavior) = OPTIONAL];

    // Optional. A query that applies a unary operator to a sub-query.
    UnaryQuery unary = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. A query that combines multiple sub-queries with a boolean
    // operator.
    CombinedQuery combine = 3 [(google.api.field_behavior) = OPTIONAL];
  }

  // Optional. Optional multiplier applied to this query node's contribution to
  // the final relevance score. Must be non-negative; if unset or 0, defaults
  // to 1.0. Values greater than 1.0 increase its influence on ranking, values
  // between 0.0 and 1.0 decrease it.
  float boost = 4 [(google.api.field_behavior) = OPTIONAL];
}

// A leaf-level text query targeting one or more data fields. When multiple
// fields are specified, this is equivalent to combining per-field matches with
// an OR operator (i.e. the query matches if the text is found in any of the
// listed fields).
message TextQuery {
  // The matching strategy to apply when comparing `text` against the content
  // of `fields`.
  enum MatchType {
    // Defaults to `STANDARD`.
    MATCH_TYPE_UNSPECIFIED = 0;

    // Treats `text` as individual search terms combined with an implicit
    // AND: every term must appear in the field, in any order and any
    // position. Case-insensitive.
    TEXT = 1;

    // Matches only when the entire field value is exactly equal to `text`.
    EXACT = 2;
  }

  // Required. The text to search for.
  string text = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The data fields to search against.
  repeated string fields = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. The matching strategy to apply for this query. If unset, defaults
  // to `STANDARD`.
  MatchType match_type = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The query enhancement settings to apply for this query.
  QueryEnhancement query_enhancement = 4
      [(google.api.field_behavior) = OPTIONAL];
}

// Query enhancement settings. When enabled, expands the search terms with
// stemming, synonyms, and spelling corrections, and removes stop words.
message QueryEnhancement {
  // Optional. Whether query enhancement is enabled.
  bool enabled = 1 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The IETF BCP 47 language tag, such as "en-US", for query
  // enhancement. If unset, the language is detected automatically. See
  // <https://en.wikipedia.org/wiki/IETF_language_tag>.
  string language_code = 2 [(google.api.field_behavior) = OPTIONAL];
}

// A query that applies a unary operator to a sub-query.
message UnaryQuery {
  // Unary operators applicable to a sub-query.
  enum Operator {
    // Default value. This value is unused.
    OPERATOR_UNSPECIFIED = 0;

    // Negates the sub-query.
    NOT = 1;
  }

  // Required. The unary operator to apply.
  Operator op = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The sub-query the operator is applied to.
  StructuredQuery sub_query = 2 [(google.api.field_behavior) = REQUIRED];
}

// A query that combines multiple sub-queries with a boolean operator.
message CombinedQuery {
  // Boolean operators used to combine sub-queries.
  enum Operator {
    // Default value. This value is unused.
    OPERATOR_UNSPECIFIED = 0;

    // All sub-queries must match.
    AND = 1;

    // At least one sub-query must match.
    OR = 2;
  }

  // Required. The boolean operator used to combine the sub-queries.
  Operator op = 1 [(google.api.field_behavior) = REQUIRED];

  // Required. The sub-queries to be combined.
  repeated StructuredQuery sub_queries = 2
      [(google.api.field_behavior) = REQUIRED];
}

// Request for performing a single search.
message SearchDataObjectsRequest {
  // The query to search for.
  oneof search_type {
    // A vector search operation.
    VectorSearch vector_search = 2;

    // A semantic search operation.
    SemanticSearch semantic_search = 4;

    // Optional. A text search operation.
    TextSearch text_search = 7 [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. The resource name of the Collection for which to search.
  // Format: `projects/{project}/locations/{location}/collections/{collection}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "vectorsearch.googleapis.com/Collection"
    }
  ];

  // Optional. The standard list page size. Only supported for KNN. If not set,
  // up to search_type.top_k results will be returned. The maximum value is
  // 1000; values above 1000 will be coerced to 1000.
  int32 page_size = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The standard list page token.
  // Typically obtained via
  // [SearchDataObjectsResponse.next_page_token][google.cloud.vectorsearch.v1beta.SearchDataObjectsResponse.next_page_token]
  // of the previous
  // [DataObjectSearchService.SearchDataObjects][google.cloud.vectorsearch.v1beta.DataObjectSearchService.SearchDataObjects]
  // call.
  string page_token = 6 [(google.api.field_behavior) = OPTIONAL];
}

// A single search result.
message SearchResult {
  // Quality signals describing how this result was retrieved, combined and
  // re-ranked. Only populated when
  // [BatchSearchDataObjectsRequest.BatchSearchMetadataOptions.search_signals_enabled][google.cloud.vectorsearch.v1beta.BatchSearchDataObjectsRequest.BatchSearchMetadataOptions.search_signals_enabled]
  // is `true`.
  message SearchResultMetadata {
    // The rank and distance of this data object within a single search of the
    // batch.
    message SearchDistance {
      // Output only. The index of the search in the
      // [BatchSearchDataObjectsRequest.searches][google.cloud.vectorsearch.v1beta.BatchSearchDataObjectsRequest.searches]
      // this distance corresponds to.
      int32 search_index = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

      // Output only. The order of this data object in the search's result list,
      // starting at 1 for the top (best-ranked) result.
      int32 rank = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

      // Output only. The similarity distance of this data object for the
      // search.
      double distance = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
    }

    // The rank and score assigned by the Reciprocal Rank Fusion ranker when
    // combining the results of the batch searches.
    message RrfRankerResult {
      // Output only. The rank of this data object after RRF combination.
      int32 rank = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

      // Output only. The score of this data object after RRF combination.
      double score = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
    }

    // The rank and score assigned by the Vertex re-ranker.
    message VertexRankerResult {
      // Output only. The rank of this data object after Vertex re-ranking.
      int32 rank = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

      // Output only. The score of this data object after Vertex re-ranking.
      double score = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
    }

    // Output only. The per-search distances for this data object, one entry per
    // batch search that returned it.
    repeated SearchDistance search_distances = 1
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The RRF combination signals for this data object. Only set
    // when the request combines results using RRF.
    RrfRankerResult rrf_ranker_result = 2
        [(google.api.field_behavior) = OUTPUT_ONLY];

    // Output only. The Vertex re-ranking signals for this data object. Only set
    // when the request re-ranks results using the Vertex ranker.
    VertexRankerResult vertex_ranker_result = 3
        [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Output only. The matching data object.
  DataObject data_object = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Similarity distance or ranker score returned by
  // BatchSearchDataObjects.
  optional double distance = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Quality signals for this result. Only populated when
  // [BatchSearchDataObjectsRequest.BatchSearchMetadataOptions.search_signals_enabled][google.cloud.vectorsearch.v1beta.BatchSearchDataObjectsRequest.BatchSearchMetadataOptions.search_signals_enabled]
  // is `true`.
  SearchResultMetadata search_result_metadata = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Metadata about the search execution.
message SearchResponseMetadata {
  // Message that indicates the index used for the search.
  message IndexInfo {
    // Output only. The resource name of the index used for the search.
    // Format:
    // `projects/{project}/locations/{location}/collections/{collection}/indexes/{index}`
    string name = 1 [
      (google.api.field_behavior) = OUTPUT_ONLY,
      (google.api.resource_reference) = {
        type: "vectorsearch.googleapis.com/Index"
      }
    ];
  }

  // The type of index used.
  oneof index_type {
    // Indicates that the search used a particular index.
    IndexInfo used_index = 1;

    // Output only. If true, the search used the system's default
    // K-Nearest Neighbor (KNN) index engine.
    bool used_knn = 2 [(google.api.field_behavior) = OUTPUT_ONLY];
  }

  // Output only. Warnings or non-fatal errors that occurred during execution.
  repeated google.rpc.Status warnings = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Response for a search request.
message SearchDataObjectsResponse {
  // Output only. The list of dataObjects that match the search criteria.
  repeated SearchResult results = 1 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A token to retrieve next page of results.
  // Pass to [DataObjectSearchService.SearchDataObjectsRequest.page_token][] to
  // obtain that page.
  string next_page_token = 2 [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. Metadata about the search execution.
  SearchResponseMetadata search_response_metadata = 3
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Request message for
// [DataObjectSearchService.AggregateDataObjects][google.cloud.vectorsearch.v1beta.DataObjectSearchService.AggregateDataObjects].
message AggregateDataObjectsRequest {
  // Required. The resource name of the Collection for which to query.
  // Format: `projects/{project}/locations/{location}/collections/{collection}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "vectorsearch.googleapis.com/Collection"
    }
  ];

  // Optional. A JSON filter expression, e.g. {"genre": {"$eq": "sci-fi"}},
  // represented as a google.protobuf.Struct.
  google.protobuf.Struct filter = 2 [(google.api.field_behavior) = OPTIONAL];

  // Required. The aggregation method to apply to the query.
  AggregationMethod aggregate = 3 [(google.api.field_behavior) = REQUIRED];
}

// Response message for
// [DataObjectSearchService.AggregateDataObjects][google.cloud.vectorsearch.v1beta.DataObjectSearchService.AggregateDataObjects].
message AggregateDataObjectsResponse {
  // Output only. The aggregated results of the query.
  repeated google.protobuf.Struct aggregate_results = 1
      [(google.api.field_behavior) = OUTPUT_ONLY];
}

// Request message for
// [DataObjectSearchService.QueryDataObjects][google.cloud.vectorsearch.v1beta.DataObjectSearchService.QueryDataObjects].
message QueryDataObjectsRequest {
  // Required. The resource name of the Collection for which to query.
  // Format: `projects/{project}/locations/{location}/collections/{collection}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "vectorsearch.googleapis.com/Collection"
    }
  ];

  // Optional. A JSON filter expression, e.g. {"genre": {"$eq": "sci-fi"}},
  // represented as a google.protobuf.Struct.
  google.protobuf.Struct filter = 2 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Mask specifying which fields to return.
  OutputFields output_fields = 7 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The standard list page size. Default is 100.
  // The maximum value is 1000; values above 1000 will be coerced to 1000.
  int32 page_size = 5 [(google.api.field_behavior) = OPTIONAL];

  // Optional. The standard list page token.
  // Typically obtained via
  // [QueryDataObjectsResponse.next_page_token][google.cloud.vectorsearch.v1beta.QueryDataObjectsResponse.next_page_token]
  // of the previous
  // [DataObjectSearchService.QueryDataObjects][google.cloud.vectorsearch.v1beta.DataObjectSearchService.QueryDataObjects]
  // call.
  string page_token = 6 [(google.api.field_behavior) = OPTIONAL];
}

// Response message for
// [DataObjectSearchService.QueryDataObjects][google.cloud.vectorsearch.v1beta.DataObjectSearchService.QueryDataObjects].
message QueryDataObjectsResponse {
  // Output only. The list of dataObjects that match the query.
  repeated DataObject data_objects = 4
      [(google.api.field_behavior) = OUTPUT_ONLY];

  // Output only. A token to retrieve next page of results.
  // Pass to [DataObjectSearchService.QueryDataObjectsRequest.page_token][] to
  // obtain that page.
  string next_page_token = 3 [(google.api.field_behavior) = OUTPUT_ONLY];
}

// A request to perform a batch of search operations.
message BatchSearchDataObjectsRequest {
  // Options for combining the results of the batch search operations.
  message CombineResultsOptions {
    // Required. The ranker to use for combining the results.
    Ranker ranker = 1 [(google.api.field_behavior) = REQUIRED];

    // Optional. Mask specifying which fields to return.
    OutputFields output_fields = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The number of results to return. If not set, a default value
    // will be used.
    int32 top_k = 3 [(google.api.field_behavior) = OPTIONAL];
  }

  // Options controlling which metadata is included in the search results.
  message BatchSearchMetadataOptions {
    // Optional. If `true`, per-result quality signals are returned in
    // [SearchResult.search_result_metadata][google.cloud.vectorsearch.v1beta.SearchResult.search_result_metadata].
    bool search_signals_enabled = 1 [(google.api.field_behavior) = OPTIONAL];
  }

  // Required. The resource name of the Collection for which to search.
  // Format: `projects/{project}/locations/{location}/collections/{collection}`
  string parent = 1 [
    (google.api.field_behavior) = REQUIRED,
    (google.api.resource_reference) = {
      type: "vectorsearch.googleapis.com/Collection"
    }
  ];

  // Required. A list of search requests to execute in parallel.
  repeated Search searches = 2 [(google.api.field_behavior) = REQUIRED];

  // Optional. Options for combining the results of the batch search operations.
  CombineResultsOptions combine = 3 [(google.api.field_behavior) = OPTIONAL];

  // Optional. Options controlling which metadata is included in the search
  // results.
  BatchSearchMetadataOptions metadata_options = 4
      [(google.api.field_behavior) = OPTIONAL];
}

// Defines a ranker to combine results from multiple searches.
message Ranker {
  // The ranking method to use.
  oneof ranker {
    // Reciprocal Rank Fusion ranking.
    ReciprocalRankFusion rrf = 1;
  }

  // The reranker to use for final ranking of the results combined by the
  // ranker.
  oneof reranker {
    // Optional. Vertex AI ranking.
    VertexRanker vertex_ranker = 2 [(google.api.field_behavior) = OPTIONAL];
  }
}

// Defines the Reciprocal Rank Fusion (RRF) algorithm for result ranking.
message ReciprocalRankFusion {
  // Required. The weights to apply to each search result set during fusion.
  repeated double weights = 1 [(google.api.field_behavior) = REQUIRED];
}

// Defines a ranker using the Vertex AI ranking service.
// See <https://cloud.google.com/generative-ai-app-builder/docs/ranking> for
// details.
message VertexRanker {
  // The record spec for text search.
  message TextRecordSpec {
    // Required. The query against which the records are ranked and scored.
    string query = 1 [(google.api.field_behavior) = REQUIRED];

    // Optional. The template used to generate the record's title.
    string title_template = 2 [(google.api.field_behavior) = OPTIONAL];

    // Optional. The template used to generate the record's content.
    string content_template = 3 [(google.api.field_behavior) = OPTIONAL];
  }

  // The record specification for ranking. At least one record spec must be
  // set.
  oneof record_spec {
    // The record spec for text search.
    TextRecordSpec text_record_spec = 6;
  }

  // Required. The model used for ranking documents. The list of available
  // models is described in
  // <https://docs.cloud.google.com/generative-ai-app-builder/docs/ranking#models>.
  // Currently, only `semantic-ranker-fast@latest` is supported.
  string model = 4 [(google.api.field_behavior) = REQUIRED];

  // Required. The number of documents to be processed for ranking.
  int32 top_n = 5 [(google.api.field_behavior) = REQUIRED];
}

// A response from a batch search operation.
message BatchSearchDataObjectsResponse {
  // Output only. A list of search responses, one for each request in the batch.
  // If a ranker is used, a single ranked list of results is returned.
  repeated SearchDataObjectsResponse results = 1
      [(google.api.field_behavior) = OUTPUT_ONLY];
}
