Approximate kNN search
Approximate kNN search uses graph-based or clustered index structures to find similar vectors quickly at scale. Use it for most production workloads where you need low latency at scale. This page covers approximate kNN search methods, a basic example, mapping defaults, indexing considerations, and vector index mode.
If you use semantic_text fields, query them with a match query for the simplest approach, or use the knn query when you need more control over the search.
Approximate kNN search has specific resource requirements. For instance, for HNSW, all vector data must fit in the node’s page cache for efficient performance. Refer to the approximate kNN tuning guide for configuration tips.
Elasticsearch provides three ways to run approximate kNN search, with different field type support:
| Method | Supported field types | Use case |
|---|---|---|
Top-level knn option |
dense_vector |
Standalone kNN search or hybrid search with score fusion |
knn query |
dense_vector, semantic_text |
Composable with other queries in a bool clause. Required for semantic_text fields |
knn retriever |
dense_vector |
Use within a retriever pipeline for ranking and result merging |
Follow these steps to map dense_vector fields, index embeddings, and run a basic approximate kNN query.
Map one or more
dense_vectorfields. Approximate kNN search is enabled by default, so no extra mapping options are required.Optionally, you can configure additional parameters, including the similarity metric, index options, and quantization. Refer to
dense_vectorfor the full list of parameters.PUT image-index{ "mappings": { "properties": { "image-vector": { "type": "dense_vector", "similarity": "l2_norm" }, "title": { "type": "text" }, "file-type": { "type": "keyword" } } } }Index your data with embeddings. If you don't have vectors yet, refer to Bring your own dense vectors for options on generating or sourcing them.
POST image-index/_bulk?refresh=true{ "index": { "_id": "1" } } { "image-vector": [1, 5, -20], "title": "moose family", "file-type": "jpg" } { "index": { "_id": "2" } } { "image-vector": [42, 8, -15], "title": "alpine lake", "file-type": "png" } { "index": { "_id": "3" } } { "image-vector": [15, 11, 23], "title": "full moon", "file-type": "jpg" } ...Query using the
knnoption:POST image-index/_search{ "knn": { "field": "image-vector", "query_vector": [-5, 9, -12], "k": 10 } }Alternatively, use a
knnquery, which you can combine with other queries in aboolclause:POST image-index/_search{ "query": { "knn": { "field": "image-vector", "query_vector": [-5, 9, -12], "k": 10 } } }
The document _score is a positive float calculated based on the chosen vector similarity metric. Refer to similarity for details on how kNN scores are computed.
Approximate kNN works without any explicit mapping options. Unless you set them, Elasticsearch applies these defaults:
| Parameter | Default |
|---|---|
index |
true, so the field is searchable with approximate kNN |
element_type |
float |
dims |
Inferred from the first vector indexed into the field |
similarity |
cosine, except for bit vectors, which use l2_norm |
index_options.type |
float and bfloat16 vectors are quantized automatically, using BBQ where available and int8_hnsw for low-dimensional vectors. byte and bit vectors are not quantized. |
The index_options.type default is particularly important: by default your float vectors are quantized, which is what keeps memory use manageable at scale. Refer to Default quantization types for how the default is chosen, and to Optimize performance and accuracy if you need to override it.
For approximate kNN, Elasticsearch indexes dense vector values as an HNSW graph or as clusters using DiskBBQ. Building these structures is compute-intensive. GPU-accelerated vector indexing is also supported. To reduce memory use and speed up vector distance calculations, Elasticsearch also quantizes vectors.
Quantization comes at the expense of recall, which you can compensate for by oversampling and rescoring more vectors. The hnsw and bbq_disk types each come with their own settings to balance recall, indexing speed, and vector search speed.
For guidance on choosing and tuning these settings, refer to the approximate kNN tuning guide. When defining your dense_vector mapping, use index_options to set these parameters.
If an index is used primarily for vector search, create it with the vectordb_document index mode to get defaults tuned for vector workloads:
PUT my-vector-index
{
"settings": {
"index": {
"mode": "vectordb_document"
}
}
}
In this mode, Elasticsearch encodes vectors as bfloat16 to halve raw vector storage, excludes vector values from _source, preloads vector index files into the filesystem cache, and tunes merging for vector data.
Refer to Index modes for vector search for the full list of applied settings.
- Tune approximate kNN search: Production guidance for vector memory, node sizing, indexing, filesystem cache, and on-disk rescoring.
- Profile kNN search: Inspect query timing and vector operation counts to diagnose slow kNN searches.
dense_vectorfield type: API reference for vector field mapping, includingindex,similarity,index_options, and quantization parameters.knnquery: API reference for theknnquery, including parameters,query_vector_builderoptions, and usage withdense_vectorandsemantic_textfields.