All Products
Search
Document Center

Elasticsearch:Vector cluster recall mode

Last Updated:Oct 14, 2026

This topic describes how to configure and use vector cluster recall mode: create a Collection, pre-create Backings, register Slice centroids, write vector data, select candidate Slices automatically at query time, and control vector retrieval within the selected Slices. For information about the feature positioning, scenarios, and mode selection, see .

The mode is determined by the creation parameter slice_strategy=vector_cluster and cannot be changed after the Collection is created. To switch an existing Collection to another mode, you must create a new Collection and import the data again. For general management and data APIs, see API reference.

The sections below follow the execution order of the workflow. One ordering constraint is mandatory: keep auto_create_slice=false, register the Slice centroids, and then write data. A Slice that has no centroid never participates in automatic candidate Slice selection, so data written to such a Slice can never be recalled automatically.

Create a Collection

In vector cluster recall mode, each vector cluster corresponds to one Slice, and the centroid of the cluster is registered as the centroid of that Slice. The following example uses three manually constructed vector clusters to verify the workflow. Two candidate Slices are queried by default, and at most three Slices can be queried. These values apply only to this example. In a production environment, use actual clustering results and determine the number of candidate Slices based on recall, latency, and resource overhead.

PUT /_slice_collection/products
{
  "slice_strategy": "vector_cluster",
  "auto_create_slice": false,
  "settings": {
    "index.number_of_shards": 2,
    "index.number_of_replicas": 2
  },
  "mappings": {
    "properties": {
      "cluster_id": { "type": "keyword" },
      "name": { "type": "keyword" },
      "embedding": {
        "type": "dense_vector",
        "dims": 2,
        "index": true,
        "similarity": "cosine",
        "index_options": {
          "type": "bbq_disk"
        }
      }
    }
  },
  "config": {
    "routing_field": "cluster_id",
    "vector_dims": 2,
    "default_query_vector_path": "knn.query_vector",
    "default_query_slice_count": 2,
    "max_query_slice_count": 3
  }
}

config is a required parameter of vector cluster recall mode:

config parameter

Required

Description

routing_field

No

Reads the Slice from a top-level field of the document that is written. Nested paths in the a.b format are not supported.

vector_dims

Yes

The vector dimensions of the Slice centroid. Valid values: 1 to 4096. The dimensions of every centroid that you register must match this value.

default_query_vector_path

Yes

The path of the query vector in the request. Valid values: knn.query_vector and knn.N.query_vector. N starts from 0, and knn.query_vector is equivalent to the query vector of the first KNN clause.

default_query_slice_count

No

The default number of candidate Slices per query. Default value: 128. Valid values: 1 to 10000. If you set this parameter to a value greater than max_query_slice_count (default value: 512), you must increase max_query_slice_count in the same request. Otherwise, an HTTP 400 error is returned.

max_query_slice_count

No

The maximum number of candidate Slices allowed in a single query. The request-level query_slice_count cannot exceed this limit. Default value: 512. Valid values: 1 to 10000. The value cannot be less than default_query_slice_count.

If you pass a non-empty config in namespace mode, which uses the slice_strategy value exact, an HTTP 400 error is returned.

vector_dims specifies the dimensions of the centroid, whereas mappings uses dense_vector.dims to specify the dimensions of document vectors. During automatic Slice selection, the query vector specified by default_query_vector_path must have the same dimensions as the centroid. This example uses the same knn.query_vector for Slice selection and document retrieval, so both dimensions are set to 2 and the same vector model is used. Changing vector_dims alone does not automatically reduce the dimensions of existing vectors.

The remaining creation parameters, such as settings, mappings, and capacity parameters, are the same as those in namespace mode. For more information, see Collection management reference. Note the following two differences in default values:

Parameter

Default value in namespace mode

Default value in vector cluster recall mode

auto_create_slice

true

false

index.sliced_postings.enabled

true

false

auto_create_slice is disabled by default because a vector cluster must register a centroid before it can participate in automatic Slice selection. Automatic creation during a write produces Slices that have no centroid, and their data can never be recalled automatically. Unless your business can accept this behavior, keep auto_create_slice=false, register the centroids first, and then write data.

Pre-create Backings (optional, recommended)

Backings are created on demand by default. Before a bulk import, pre-create five underlying indexes so that the data of new vector clusters is distributed across them and the wait for index creation during the first write is reduced. In a production environment, adjust the number based on vector cluster growth, data volume, and shard resources.

PUT /_slice_collection/products/backings?count=5

Verify that acknowledged=true and that backings contains five indexes. Pre-creation does not migrate existing Slices and does not generate centroids. For information about the semantics of adding more Backings and the changes to the allocation policy, see Pre-create Backings.

Register Slice centroids

Every Slice that participates in automatic Slice selection must have a centroid. You cannot skip this step. Centroid retrieval always runs an approximate nearest neighbor (ANN) search with cosine similarity and a bbq_disk index. It does not change with the similarity setting of the document vector field.

Register a single Slice centroid

The following request registers the centroid of the Slice cluster-a:

PUT /_slice_collection/products/slices/cluster-a
{
  "vector": [0.9, 0.1]
}

A successful HTTP response does not guarantee that the centroid was created. As described in Check registration results (single and batch), check the top-level errors field and the result of every element in items.

Register Slice centroids in batches

An offline clustering job usually generates multiple vector cluster centroids at the same time. You can use the batch API to register them in one request:

PUT /_slice_collection/products/slices
{
  "slices": [
    { "slice": "cluster-b", "vector": [0.1, 0.9] },
    { "slice": "cluster-c", "vector": [0.6, 0.4] }
  ]
}

The Slice name of each item can be specified by slice or slice_id, but only one of them can appear in the same item. You can register up to 20,480 Slices in a single request, and Slice names must be unique within the request.

Check registration results (single and batch)

Both the single and the batch registration API can report item-level errors in an HTTP 200 response, including a mismatch between the centroid dimensions and config.vector_dims. A successful HTTP request does not mean that all vector clusters were registered successfully. In addition to handling non-2xx responses, you must check the top-level errors field and, for every element in items, its result: created indicates that the centroid was created, updated indicates that the centroid was updated, noop indicates that the content did not change, and failed indicates a failure. A failed item contains an error field of the string type and does not contain the backing_index field that a successful item contains.

{
  "acknowledged": true,
  "errors": false,
  "items": [
    {
      "slice_id": "cluster-b",
      "result": "created",
      "backing_index": ".sc-products-...-00000"
    },
    {
      "slice_id": "cluster-c",
      "result": "created",
      "backing_index": ".sc-products-...-00001"
    }
  ]
}

The dimensions of each centroid must match config.vector_dims. A Slice without a centroid can still be accessed explicitly, but it does not participate in automatic candidate Slice selection. When you register a Slice with the same name again, updated is returned if the centroid changed, and noop is returned if it did not change. In both cases, the documents that have already been written are not moved.

Write vector data

How you write documents depends on whether you configured routing_field at Collection creation. If routing_field is configured, the system reads the Slice from a top-level field of each document. If it is not configured, every write request or Bulk item must explicitly specify _slice, as in namespace mode.

Regular write requests must not pass refresh, and application code must not call _refresh. Wait for the automatic background refresh to make the data searchable. For the conditions under which a synchronous wait is allowed, see Refresh and query visibility.

Write documents with routing_field

After you configure routing_field, the system reads the Slice from a top-level field of the document, and you no longer need to pass _slice:

PUT /products/_doc/product-1
{
  "cluster_id": "cluster-a",
  "name": "example-product",
  "embedding": [0.92, 0.08]
}

You can also explicitly provide _slice=cluster-a, and compatible APIs also accept routing=cluster-a. If you explicitly specify a Slice, the value must match the value of the document field specified by routing_field (cluster_id in this example). Otherwise, an HTTP 400 error is returned.

Update documents

After you configure routing_field, scripted updates are not supported. To modify only some fields, use the _update API with a doc request body and explicitly carry a matching _slice. If a new value must be calculated from an old value, read the old value in your application, calculate the new value, and write it back. Use if_seq_no and if_primary_term for concurrency control to prevent your update from overwriting the updates of other requests.

Write back documents after Copy or Branch

The Copy and Branch features both retain the routing_field value in a document. When you later write a document back to the destination Slice, explicitly specify the destination and make sure that the routing field in the written document matches the destination. This prevents the document from being written back to the source Slice or triggering a validation error. For more information, see Copy data semantics.

Write documents without routing_field

If routing_field is not configured, data is written in the same way as in namespace mode: every write request or Bulk item must explicitly specify _slice. For other write behaviors, such as Bulk, Refresh visibility, _update_by_query, and _delete_by_query, see Document write, read, and query operations.

Automatically select candidate Slices

When a query provides a vector at the configured path, vector cluster recall mode automatically selects the candidate Slices to search. Newly written data becomes searchable only after the automatic background refresh: after the write, wait about 5 seconds, and if the results do not contain the new data yet, wait for one more automatic refresh cycle and retry.

Run a query

Use a query vector to automatically select candidate Slices:

POST /products/_search?query_slice_count=2
{
  "knn": {
    "field": "embedding",
    "query_vector": [0.91, 0.09],
    "k": 10,
    "num_candidates": 100
  }
}

Verify that timed_out=false and _shards.failed=0, and that hits.hits contains product-1 written in this example.

The following table describes the parameters of automatic candidate Slice selection:

Parameter

Description

query_slice_count

The number of candidate Slices selected for this query. If this parameter is omitted or set to 0, the default_query_slice_count of the Collection is used.

query_vector_path

Overrides the default query vector path of the Collection. Valid values: knn.query_vector and knn.N.query_vector. N starts from 0, and knn.query_vector is equivalent to the query vector of the first KNN clause.

A request uses only the one query vector selected by the configured path to determine the candidate Slices of the entire request. Multiple KNN clauses do not select Slices separately and then take the union of the selected Slice sets. Other KNN or hybrid query clauses are also restricted to this set of candidate Slices.

If query_slice_count is explicitly set to a non-zero value, the value must be within the range of 1 to max_query_slice_count. Otherwise, an HTTP 400 error is returned.

If the request explicitly specifies _slice or the compatible routing parameter, the query runs within the specified scope, regardless of whether those Slices have registered centroids. The centroid requirement applies only to automatic candidate Slice selection: only the Slices that have a registered centroid are considered.

When the cluster setting apack.slice_collection.search.default_to_all_slices is disabled, which is the default, an HTTP 400 error is returned if the configured path has no query vector. In this case, explicitly specify _slice. After you enable this setting, a missing query vector falls back to querying all Slices. For regular production queries, keep this setting disabled and do not rely on the all-Slice fallback. An invalid path, the use of query_vector_builder to provide the query vector, or query vector dimensions that do not match vector_dims still return an HTTP 400 error, and this setting cannot bypass those errors. For information about the setting, see Specify the query scope.

The request body of the Count API (_count) does not contain the inline query vector that automatic Slice selection requires, so the Slice cannot be selected automatically. While the all-Slice fallback stays disabled by default, you must explicitly provide _slice. Other queries that do not contain a query vector must also explicitly specify the scope.

Prewarm known candidate Slices (optional)

If you can predict which clusters will be accessed, prewarm them first to reduce the latency of the first query on cold data. In this example, only one document is written to cluster-a, so you can prewarm it once:

POST /products/_warm_slice?_slice=cluster-a&wait_for_completion=true&timeout=60s

Verify that the request succeeds and that _shards.failed=0. If _shards.total=0, first verify that the query shards are available and use an actual query to confirm that the data is searchable, and then retry the prewarm as needed. Data has already been written in this example. The synchronous wait is used only to verify this example. In a production environment, prewarm a predictable access scope asynchronously in advance and control the concurrency. Do not iterate over and prewarm all clusters before each automatic cluster selection query. For more information, see Warm Up the Slice Cache.

Common HTTP 400 errors

When a request returns an HTTP 400 error, compare the request against the following common causes:

Cause

Section

default_query_slice_count is set to a value greater than max_query_slice_count, and max_query_slice_count is not increased in the same request.

Create a Collection

A non-empty config is passed in namespace mode (exact).

Create a Collection

The explicitly specified _slice or routing value does not match the value of the document field specified by routing_field.

Write vector data

query_slice_count is explicitly set to a non-zero value outside the range of 1 to max_query_slice_count.

Automatically select candidate Slices

The configured path has no query vector while apack.slice_collection.search.default_to_all_slices is disabled.

Automatically select candidate Slices

The query vector path is invalid, query_vector_builder is used to provide the query vector, or the query vector dimensions do not match vector_dims. These errors are returned even when apack.slice_collection.search.default_to_all_slices is enabled.

Automatically select candidate Slices

Vector retrieval within a Slice

query_slice_count controls the number of candidate Slices, whereas the index type of the document vector field, visit_percentage, and num_candidates control KNN within the selected scope. For field and query parameters, see Vector fields and KNN. For the division of responsibilities between the two capabilities and how to choose between them, see Relationship with DiskBBQ.