navigation_title: "Semantic text" mapped_pages:
The semantic_text field type automatically generates embeddings for text
content using an inference endpoint. Long passages
are automatically chunked to smaller sections to enable
the processing of larger corpuses of text.
The semantic_text field type specifies an inference endpoint identifier that
will be used to generate embeddings. You can create the inference endpoint by
using
the Create {{infer}} API.
This field type and the
semantic query
type make it simpler to perform semantic search on your data. The
semantic_text field type may also be queried
with match, sparse_vector
or knn queries.
If you don’t specify an inference endpoint, the inference_id field defaults to
.elser-2-elasticsearch, a preconfigured endpoint for the elasticsearch
service.
Using semantic_text, you won’t need to specify how to generate embeddings for
your data, or how to index it. The {{infer}} endpoint automatically determines
the embedding generation, indexing, and query to use.
{applies_to}stack: ga 9.1 Newly created indices with semantic_text fields using dense embeddings will be
quantized
to bbq_hnsw automatically as long as they have a minimum of 64 dimensions.
You can use either preconfigured endpoints in your semantic_text fields which
are ideal for most use cases or create custom endpoints and reference them in
the field mappings.
If you use the preconfigured .elser-2-elasticsearch endpoint, you can set up
semantic_text with the following API request:
PUT my-index-000001
{
"mappings": {
"properties": {
"inference_field": {
"type": "semantic_text"
}
}
}
}
To use a custom {{infer}} endpoint instead of the default
.elser-2-elasticsearch, you
must Create {{infer}} API
and specify its inference_id when setting up the semantic_text field type.
PUT my-index-000002
{
"mappings": {
"properties": {
"inference_field": {
"type": "semantic_text",
"inference_id": "my-openai-endpoint" <1>
}
}
}
}
inference_id of the {{infer}} endpoint to use to generate embeddings.The recommended way to use semantic_text is by having dedicated {{infer}}
endpoints for ingestion and search. This ensures that search speed remains
unaffected by ingestion workloads, and vice versa. After creating dedicated
{{infer}} endpoints for both, you can reference them using the inference_id
and search_inference_id parameters when setting up the index mapping for an
index that uses the semantic_text field.
PUT my-index-000003
{
"mappings": {
"properties": {
"inference_field": {
"type": "semantic_text",
"inference_id": "my-elser-endpoint-for-ingest",
"search_inference_id": "my-elser-endpoint-for-search"
}
}
}
}
stack: preview 9.1
serverless: preview
If you use the preconfigured .elser-2-elastic endpoint that utilizes the ELSER model as a service through the Elastic Inference Service (ELSER on EIS), you can
set up semantic_text with the following API request:
PUT my-index-000001
{
"mappings": {
"properties": {
"inference_field": {
"type": "semantic_text",
"inference_id": ".elser-2-elastic"
}
}
}
}
::::{note} While we do encourage experimentation, we do not recommend implementing production use cases on top of this feature while it is in Technical Preview.
::::
semantic_text fields [semantic-text-params]inference_id
: (Optional, string) {{infer-cap}} endpoint that will be used to generate
embeddings for the field. By default, .elser-2-elasticsearch is used. This
parameter cannot be updated. Use
the Create {{infer}} API
to create the endpoint. If search_inference_id is specified, the {{infer}}
endpoint will only be used at index time.
search_inference_id
: (Optional, string) {{infer-cap}} endpoint that will be used to generate
embeddings at query time. You can update this parameter by using
the Update mapping API.
Use
the Create {{infer}} API
to create the endpoint. If not specified, the {{infer}} endpoint defined by
inference_id will be used at both index and query time.
index_options {applies_to}stack: ga 9.1
: (Optional, object) Specifies the index options to override default values
for the field. Currently, dense_vector and sparse_vector index options are supported.
For text embeddings, index_options may match any allowed.
stack: ga 9.2chunking_settings {applies_to}stack: ga 9.1
: (Optional, object) Settings for chunking text into smaller passages.
If specified, these will override the chunking settings set in the {{infer-cap}}
endpoint associated with inference_id.
If chunking settings are updated, they will not be applied to existing documents
until they are reindexed.
To completely disable chunking, use the none chunking strategy.
**Valid values for `chunking_settings`**:
`strategy`
: Indicates the strategy of chunking strategy to use. Valid values are `none`, `word` or
`sentence`. Required.
`max_chunk_size`
: The maximum number of words in a chunk. Required for `word` and `sentence` strategies.
`overlap`
: The number of overlapping words allowed in chunks. This cannot be defined as
more than half of the `max_chunk_size`. Required for `word` type chunking
settings.
`sentence_overlap`
: The number of overlapping sentences allowed in chunks. Valid values are `0`
or `1`. Required for `sentence` type chunking settings
::::{warning}
When using the none chunking strategy, if the input exceeds the maximum token
limit of the underlying model, some
services (such as OpenAI) may return an
error. In contrast, the elastic and elasticsearch services will
automatically truncate the input to fit within the
model's limit.
::::
The inference_id will not be validated when the mapping is created, but when
documents are ingested into the index. When the first document is indexed, the
inference_id will be used to generate underlying indexing structures for the
field.
::::{warning}
Removing an {{infer}} endpoint will cause ingestion of documents and semantic
queries to fail on indices that define semantic_text fields with that
{{infer}} endpoint as their inference_id. Trying
to delete an {{infer}} endpoint
that is used on a semantic_text field will result in an error.
::::
{{infer-cap}} endpoints have a limit on the amount of text they can process. To
allow for large amounts of text to be used in semantic search, semantic_text
automatically generates smaller passages if needed, called chunks.
Each chunk refers to a passage of the text and the corresponding embedding generated from it. When querying, the individual passages will be automatically searched for each document, and the most relevant passage will be used to compute a score.
For more details on chunking and how to configure chunking settings, see Configuring chunking in the Inference API documentation.
Refer
to this tutorial
to learn more about semantic search using semantic_text.
stack: ga 9.1
You can pre-chunk the input by sending it to Elasticsearch as an array of strings. Example:
PUT test-index
{
"mappings": {
"properties": {
"my_semantic_field": {
"type": "semantic_text",
"chunking_settings": {
"strategy": "none" <1>
}
}
}
}
}
Disable chunking on my_semantic_field.
PUT test-index/_doc/1
{
"my_semantic_field": ["my first chunk", "my second chunk", ...] <1>
...
}
The text is pre-chunked and provided as an array of strings. Each element in the array represents a single chunk that will be sent directly to the inference service without further chunking.
Important considerations:
none to avoid additional processing.elastic and elasticsearch) will automatically truncate
the input.You can extract the most relevant fragments from a semantic text field by using the highlight parameter in the Search API.
POST test-index/_search
{
"query": {
"match": {
"my_semantic_field": "Which country is Paris in?"
}
},
"highlight": {
"fields": {
"my_semantic_field": {
"number_of_fragments": 2, <1>
"order": "score" <2>
}
}
}
}
score. By default,
fragments will be output in the order they appear in the field (order: none).To use the semantic highlighter to view chunks in the order which they were indexed with no scoring,
use the match_all query to retrieve them in the order they appear in the document:
POST test-index/_search
{
"query": {
"match_all": {}
},
"highlight": {
"fields": {
"my_semantic_field": {
"number_of_fragments": 5 <1>
}
}
}
}
Highlighting is supported on fields other than semantic_text. However, if you
want to restrict highlighting to the semantic highlighter and return no
fragments when the field is not of type semantic_text, you can explicitly
enforce the semantic highlighter in the query:
PUT test-index
{
"query": {
"match": {
"my_field": "Which country is Paris in?"
}
},
"highlight": {
"fields": {
"my_field": {
"type": "semantic", <1>
"number_of_fragments": 2,
"order": "score"
}
}
}
}
semantic_text fields [semantic-text-updates]When updating documents that contain semantic_text fields, it’s important to understand how inference is triggered:
Full document updates
When you perform a full document update, all semantic_text fields will re-run inference even if their values did not change. This ensures that the embeddings are always consistent with the current document state but can increase ingestion costs.
Partial updates using the Bulk API
Partial updates that omit semantic_text fields and are submitted through the Bulk API will reuse the existing embeddings stored in the index. In this case, inference is not triggered for fields that were not updated, which can significantly reduce processing time and cost.
Partial updates using the Update API
When using the Update API with a doc object that omits semantic_text fields, inference will still run on all semantic_text fields. This means that even if the field values are not changed, embeddings will be re-generated.
If you want to avoid unnecessary inference and keep existing embeddings:
* Use **partial updates through the Bulk API**.
* Omit any `semantic_text` fields that did not change from the `doc` object in your request.
semantic_text indexing [custom-indexing]semantic_text uses defaults for indexing data based on the {{infer}} endpoint
specified. It enables you to quickstart your semantic search by providing
automatic {{infer}} and a dedicated query so you don’t need to provide further
details.
semantic_text parameters [custom-by-parameters]stack: ga 9.1
If you want to override those defaults and customize the embeddings that
semantic_text indexes, you can do so by
modifying parameters:
index_options to specify alternate index options such as specific
dense_vector quantization methodschunking_settings to override the chunking strategy associated with the
{{infer}} endpoint, or completely disable chunking using the none typeHere is an example of how to set these parameters for a text embedding endpoint:
PUT my-index-000004
{
"mappings": {
"properties": {
"inference_field": {
"type": "semantic_text",
"inference_id": "my-text-embedding-endpoint",
"index_options": {
"dense_vector": {
"type": "int4_flat"
}
},
"chunking_settings": {
"type": "none"
}
}
}
}
}
semantic_text fields [update-script]For indices containing semantic_text fields, updates that use scripts have the
following behavior:
semantic_text fields, the
update will fail when the index contains a semantic_text field.copy_to and multi-fields support [copy-to-support]The semantic_text field type can serve as the target of copy_to fields, be part of a multi-field structure, or contain multi-fields internally. This means you can use a single field to collect the values of other fields for semantic search.
For example, the following mapping:
PUT test-index
{
"mappings": {
"properties": {
"source_field": {
"type": "text",
"copy_to": "infer_field"
},
"infer_field": {
"type": "semantic_text",
"inference_id": ".elser-2-elasticsearch"
}
}
}
}
can also be declared as multi-fields:
PUT test-index
{
"mappings": {
"properties": {
"source_field": {
"type": "text",
"fields": {
"infer_field": {
"type": "semantic_text",
"inference_id": ".elser-2-elasticsearch"
}
}
}
}
}
}
If you want to verify that your embeddings look correct, you can view the
inference data that semantic_text typically hides using fields.
POST test-index/_search
{
"query": {
"match": {
"my_semantic_field": "Which country is Paris in?"
},
"fields": [
"_inference_fields"
]
}
}
This will return verbose chunked embeddings content that is used to perform
semantic search for semantic_text fields.
semantic_text field types have the following limitations:
semantic_text fields are not currently supported as elements
of nested fields.semantic_text fields can’t currently be set as part
of dynamic templates.semantic_text fields are not supported with Cross-Cluster Search (CCS) or
Cross-Cluster Replication (CCR).