Elasticsearch Vector Search: script_score and _knn_search Methods
This article explains Elasticsearch's vector search capabilities, detailing two approaches—script_score using dense_vector fields for exact similarity scoring and the experimental _knn_search for approximate nearest neighbor queries—along with data modeling examples, code snippets, performance considerations, and usage guidelines.
Elasticsearch Vector Search
This article introduces two ways to perform vector search in Elasticsearch.
Vector Search
When you hear “vector search”, you may wonder: what is it, what are its application scenarios, and how does it differ from traditional full‑text search?
What is vector search?
What are the application scenarios?
How does vector search differ from full‑text search?
Full‑text search in ES tokenizes text and uses the BM25 algorithm to compute relevance scores, which is a term‑based search.
Full‑text search is widely used and mature, but many data types such as images, audio, and video also need to be searchable.
The answer is Yes!
With the rise of machine learning and AI, everything can be embedded; that is, any data can be transformed into feature vectors, making vector search increasingly important.
Elasticsearch Vector Search Overview
ES currently supports two vector‑search methods:
script_score
_knn_search
script_score Exact Search
Since ES 7.6 the field type dense_vector is stable and is used to store vector data.
Data modeling example:
PUT my-index
{
"mappings": {
"properties": {
"my_vector": {
"type": "dense_vector",
"dims": 128
},
"my_text" : {
"type" : "keyword"
}
}
}
}The above creates a dense_vector field with 128 dimensions.
Search example using script_score :
{
"script_score": {
"query": {"match_all": {}},
"script": {
"source": "cosineSimilarity(params.query_vector, 'my_vector') + 1.0",
"params": {"query_vector": query_vector}
}
}
}This uses the built‑in cosineSimilarity function to compute similarity.
Note that script_score first runs the query phase and then scores the matched documents with vector similarity, which means:
Vector fields can be combined with other field types, enabling hybrid queries (full‑text followed by vector scoring).
script_score performs a brute‑force calculation, so performance degrades with larger datasets.
_knn_search
Because of the performance issues of script_score , ES 8.0 introduced the experimental _knn_search method.
_knn_search implements an approximate nearest neighbor (ANN) search, sacrificing some accuracy for speed.
Data modeling for _knn_search differs slightly:
Example:
PUT my-index-knn
{
"mappings": {
"properties": {
"my_vector": {
"type": "dense_vector",
"dims": 128,
"index": true,
"similarity": "dot_product"
}
}
}
}When using _knn_search , you must set:
index to true.
similarity to one of l2_norm , dot_product , or cosine .
Setting index to true tells ES to build an underlying HNSW graph for fast ANN search.
Search example with _knn_search :
GET my-index-knn/_knn_search
{
"knn": {
"field": "my_vector",
"query_vector": [0.3, 0.1, 1.2, ...],
"k": 10,
"num_candidates": 100
},
"_source": ["name", "date"]
}_knn_search offers very fast search speed, but its accuracy is not 100 % and it cannot be combined with the Query DSL for hybrid queries.
References
text-similarity-search-with-vectors-in-elasticsearch
dense-vector
knn-search
introducing-approximate-nearest-neighbor-search-in-elasticsearch
System Architect Go
Programming, architecture, application development, message queues, middleware, databases, containerization, big data, image processing, machine learning, AI, personal growth.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.