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:
| Required | Description |
| No | Reads the Slice from a top-level field of the document that is written. Nested paths in the |
| 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. |
| Yes | The path of the query vector in the request. Valid values: |
| No | The default number of candidate Slices per query. Default value: |
| No | The maximum number of candidate Slices allowed in a single query. The request-level |
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 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=5Verify 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 |
| The number of candidate Slices selected for this query. If this parameter is omitted or set to |
| Overrides the default query vector path of the Collection. Valid values: |
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=60sVerify 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 |
| Create a Collection |
A non-empty | Create a Collection |
The explicitly specified | Write vector data |
| Automatically select candidate Slices |
The configured path has no query vector while | Automatically select candidate Slices |
The query vector path is invalid, | 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.