The use of embeddings to improve the relevance and accuracy of information retrieval has grown significantly over the years. Tools like Elasticsearch have evolved to support this type of data through specialized field types such as dense vectors, sparse vectors, and semantic text. However, to achieve good results, it is essential to understand how to properly map embeddings to the available Elasticsearch field types: semantic_text
, dense_vector
, and sparse_vector
.
In this article, we will discuss these field types, when to use each one, and how they relate to embedding generation and usage strategies, both during indexing and querying.
Dense vector type
The dense_vector
field type in Elasticsearch is used to store dense vectors, which are numerical representations of data such as text, images and audio, where almost all dimensions are relevant.. These vectors are generated using embedding models provided by platforms such as OpenAI, Cohere, or Hugging Face, and are designed to capture the overall semantic meaning of the data, even when it does not share exact terms with other documents.
In Elasticsearch, dense vectors can have up to 4096 dimensions depending on the model used. For example, the all-MiniLM-L6-v2 model generates vectors with 384 dimensions, while OpenAI’s text-embedding-ada-002 produces vectors with 1536 dimensions.
The dense_vector
field is commonly adopted as the default type for storing this kind of embedding when greater control is needed, such as using pre-generated vectors, applying custom similarity functions, or integrating with external models.
When and why to use dense_vector type?
Dense vectors are excellent for capturing semantic similarity between sentences, paragraphs, or entire documents. They work very well when the goal is to compare the overall meaning of texts, even if they do not share the same terms.
The dense vector field is ideal when you already have an external embedding generation pipeline using models provided by platforms such as OpenAI, Cohere, or Hugging Face and only want to store and query these vectors manually. This type of field offers high compatibility with embedding models and full flexibility in generation and querying, allowing you to control how the vectors are produced, indexed, and used during search.
In addition, it supports different forms of semantic search, with queries such as k-NN or script_score for cases where it is necessary to adjust the ranking logic. These possibilities make the dense vector ideal for applications such as RAG (Retrieval-Augmented Generation), recommendation systems, and personalized searches based on similarity.
Finally, the field allows you to customize the relevance logic, using functions such as cosineSimilarity
, dotProduct
or l2norm
to adapt the ranking according to the needs of your use case.
Dense vectors remain the best option for those who need flexibility, customization, and compatibility with advanced use cases like the ones mentioned above.
How to use the query for dense vector type?
Searches on fields defined as dense_vector
use the k-nearest neighbors query. This query is responsible for finding documents whose dense vector is closest to the query vector. Below is an example of how to apply a k-NN query to a dense vector field:
{
"knn": {
"field": "my_dense_vector",
"k": 10,
"num_candidates": 50,
"query_vector": [/* vector generated by model */]
}
}
In addition to the k-NN query, if there is a need to customize the document scoring, it is also possible to use the script_score query, combining it with vector comparison functions such as cosineSimilarity, dotProduct, or l2norm to calculate relevance in a more controlled way. See the example:
{
"script_score": {
"query": { "match_all": {} },
"script": {
"source": "cosineSimilarity(params.query_vector,
'my_dense_vector') + 1.0",
"params": {
"query_vector": [/* vector */]
}
}
}
}
If you want to dive deeper, I recommend exploring the article How to set up vector search in Elasticsearch.
Sparse vector type
The sparse_vector
field type is used to store sparse vectors, which are numerical representations where most values are zero and only a few terms have significant weights. This type of vector is common in term-based models such as SPLADE or ELSER (Elastic Learned Sparse EncodeR).
When and why to use sparse vector type?
Sparse vectors are ideal when you need a more precise search in lexical terms, without sacrificing semantic intelligence. They represent the text as token/value pairs, highlighting only the most relevant terms with associated weights, which provides clarity, control and efficiency.
This type of field is especially useful when you generate vectors based on terms, such as in the ELSER or SPLADE models, which assign different weights to each token based on its relative importance in the text.
For the occasions when you want to control the influence of specific words in the query, sparse vector types allow you to manually adjust the weight of the terms to optimize the ranking of the results.
Among the main benefits are transparency in the search since it is possible to clearly understand why a document was considered relevant, and storage efficiency since only tokens with a non-zero value are saved, unlike dense vectors that store all dimensions.
Furthermore, sparse vectors are the ideal complement in hybrid search strategies, and can even be combined with dense vectors to combine lexical precision with semantic understanding.
How to use the query for sparse vector type?
The sparse_vector
query allows you to search for documents based on a query vector in token/value format. See an example of the query below:
{
"query": {
"sparse_vector": {
"field": "field_sparse",
"query_vector": {
"token1": 0.6,
"token2": 0.2,
"token3": 0.9
}
}
}
}
If you prefer to use a trained model, it is possible to use an inference endpoint that automatically transforms the query text into a sparse vector:
{
"query": {
"sparse_vector": {
"field": "field_sparse",
"inference_id": "the inference ID to produce the token/weights",
"query": "search text"
}
}
}
To explore this topic further, I suggest reading Understanding sparse vector embeddings with trained ML models.
Semantic text type
The semantic_text
field type is the simplest and most straightforward way to use semantic search in Elasticsearch. It automatically handles embedding generation, both at indexing and query time, through an inference endpoint. This means you don’t have to worry about generating or storing vectors manually.
When and why to use semantic text?
The semantic_text
field is is ideal for those who want to get started with minimal technical effort and without having to handle vectors manually. This field automates steps like embedding generation and vector search mapping, making the setup faster and more convenient.
You should consider using semantic_text
when you value simplicity and abstraction, as it eliminates the complexity of manually configuring mappings, embedding generation, and ingestion pipelines. Just select the inference model, and Elasticsearch takes care of the rest.
Key advantages include automatic embedding generation, performed during both indexing and querying, and ready-to-use mapping, which comes preconfigured to support the selected inference model.
In addition, the field offers native support for automatic splitting of long texts (text chunking), allowing large texts to be divided into smaller passages, each with its own embedding, which improves search precision. This greatly boosts productivity, especially for teams that want to deliver value quickly without dealing with the underlying engineering of semantic search.
However, while semantic_text
provides speed and simplicity, this approach has some limitations. It allows the use of market standard models, as long as they are available as inference endpoints in Elasticsearch. But it does not support externally generated embeddings, as is possible with the dense_vector
field.
If you need more control over how vectors are generated, want to use your own embeddings, or need to combine multiple fields for advanced strategies, the dense_vector
and sparse_vector
fields provide the flexibility required for more customized or domain-specific scenarios.
How to use the query for semantic text type
Before semantic_text
, it was necessary to use a different query depending on the type of embedding (dense or sparse). A sparse_vector
query was used for sparse fields, while dense_vector
fields required KNN queries.
With the semantic text type, the search is performed using the semantic query, which automatically generates the query vector and compares it with the embeddings of the indexed documents. The semantic_text
type allows you to define an inference endpoint to embed the query, but if none is specified, the same endpoint used during indexing will be applied to the query.
{
"query": {
"semantic": {
"field": "semantic_text_field",
"query": "search text"
}
}
}
To learn more, I suggest reading the article Elasticsearch new semantic_text mapping: Simplifying semantic search.
Conclusion
When choosing how to map embeddings in Elasticsearch, it is essential to understand how you want to generate the vectors and what level of control you need over them. If you are looking for simplicity, the semantic text field enables automatic and scalable semantic search, making it ideal for many initial use cases. When more control, fine-tuned performance, or integration with custom models is required, the dense vector and sparse vector fields provide the necessary flexibility.
The ideal field type depends on your use case, available infrastructure, and the maturity of your machine learning stack. Most importantly, Elastic offers the tools to build modern and highly adaptable search systems.
References
- Semantic text field type
- Sparse vector field type
- Dense vector field type
- Semantic query
- Sparse vector query
- kNN search
- Elasticsearch new semantic_text mapping: Simplifying semantic search
- Understanding sparse vector embeddings with trained ML models
Ready to try this out on your own? Start a free trial.
Elasticsearch has integrations for tools from LangChain, Cohere and more. Join our advanced semantic search webinar to build your next GenAI app!
Related content

September 8, 2025
MCP for intelligent search
Building an intelligent search system by integrating Elastic's intelligent query layer with MCP to enhance the generative efficacy of LLMs.

September 3, 2025
Vector search filtering: Keep it relevant
Performing vector search to find the most similar results to a query is not enough. Filtering is often needed to narrow down search results. This article explains how filtering works for vector search in Elasticsearch and Apache Lucene.

August 12, 2025
Beyond similar names: How Elasticsearch semantic text exceeds OpenSearch semantic field in simplicity, efficiency, and integration
Comparing Elasticsearch semantic text and OpenSearch semantic field in terms of simplicity, configurability, and efficiency.

August 26, 2025
Lighter by default: Excluding vectors from source
Elasticsearch now excludes vectors from source by default, saving space and improving performance while keeping vectors accessible when needed.

August 8, 2025
Using Direct IO for vector searches
Using rescoring for kNN vector searches improves search recall, but can increase latency. Learn how to reduce this impact by leveraging direct IO.