Semantic text field type
editSemantic text field type
editThis functionality is in beta and is subject to change. The design and code is less mature than official GA features and is being provided as-is with no warranties. Beta features are not subject to the support SLA of official GA features.
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 inference API.
This field type and the semantic
query type make it simpler to perform semantic search on your data.
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 inference endpoint automatically determines the embedding generation, indexing, and query to use.
If you use the preconfigured .elser-2-elasticsearch
endpoint, you can set up semantic_text
with the following API request:
const response = await client.indices.create({ index: "my-index-000001", mappings: { properties: { inference_field: { type: "semantic_text", }, }, }, }); console.log(response);
PUT my-index-000001 { "mappings": { "properties": { "inference_field": { "type": "semantic_text" } } } }
To use a custom inference endpoint instead of the default .elser-2-elasticsearch
, you must Create inference API and specify its inference_id
when setting up the semantic_text
field type.
const response = await client.indices.create({ index: "my-index-000002", mappings: { properties: { inference_field: { type: "semantic_text", inference_id: "my-openai-endpoint", }, }, }, }); console.log(response);
PUT my-index-000002 { "mappings": { "properties": { "inference_field": { "type": "semantic_text", "inference_id": "my-openai-endpoint" } } } }
The recommended way to use semantic_text
is by having dedicated inference endpoints for ingestion and search.
This ensures that search speed remains unaffected by ingestion workloads, and vice versa.
After creating dedicated inference 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.
const response = await client.indices.create({ index: "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", }, }, }, }); console.log(response);
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" } } } }
Parameters for semantic_text
fields
edit-
inference_id
-
(Required, string)
Inference 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 inference API to create the endpoint. Ifsearch_inference_id
is specified, the inference endpoint will only be used at index time. -
search_inference_id
-
(Optional, string)
Inference 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 inference API to create the endpoint.
If not specified, the inference endpoint defined by
inference_id
will be used at both index and query time.
Inference endpoint validation
editThe 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.
Removing an inference endpoint will cause ingestion of documents and semantic queries to fail on indices that define semantic_text
fields with that inference endpoint as their inference_id
.
Trying to delete an inference endpoint that is used on a semantic_text
field will result in an error.
Text chunking
editInference 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
and the semantic
query.
Extracting Relevant Fragments from Semantic Text
editYou can extract the most relevant fragments from a semantic text field by using the highlight parameter in the Search API.
const response = await client.indices.create({ index: "test-index", query: { semantic: { field: "my_semantic_field", }, }, highlight: { fields: { my_semantic_field: { type: "semantic", number_of_fragments: 2, order: "score", }, }, }, }); console.log(response);
PUT test-index { "query": { "semantic": { "field": "my_semantic_field" } }, "highlight": { "fields": { "my_semantic_field": { "type": "semantic", "number_of_fragments": 2, "order": "score" } } } }
Specifies the maximum number of fragments to return. |
|
Sorts highlighted fragments by score when set to |
Customizing semantic_text
indexing
editsemantic_text
uses defaults for indexing data based on the inference endpoint
specified. It enables you to quickstart your semantic search by providing
automatic inference and a dedicated query so you don’t need to provide further
details.
In case you want to customize data indexing, use the
sparse_vector
or dense_vector
field
types and create an ingest pipeline with an
inference processor to generate the embeddings.
This tutorial walks you through the process. In
these cases - when you use sparse_vector
or dense_vector
field types instead
of the semantic_text
field type to customize indexing - using the
semantic_query
is not supported for querying the
field data.
Updates to semantic_text
fields
editUpdates that use scripts are not supported for an index contains a semantic_text
field.
Even if the script targets non-semantic_text
fields, the update will fail when the index contains a semantic_text
field.
copy_to
support
editThe semantic_text
field type can be the target of
copy_to
fields. This means you can use a single semantic_text
field to collect the values of other fields for semantic search. Each value has
its embeddings calculated separately; each field value is a separate set of chunk(s) in
the resulting embeddings.
This imposes a restriction on bulk requests and ingestion pipelines that update documents with semantic_text
fields.
In these cases, all fields that are copied to a semantic_text
field, including the semantic_text
field value, must have a value to ensure every embedding is calculated correctly.
For example, the following mapping:
const response = await client.indices.create({ index: "test-index", mappings: { properties: { infer_field: { type: "semantic_text", inference_id: ".elser-2-elasticsearch", }, source_field: { type: "text", copy_to: "infer_field", }, }, }, }); console.log(response);
PUT test-index { "mappings": { "properties": { "infer_field": { "type": "semantic_text", "inference_id": ".elser-2-elasticsearch" }, "source_field": { "type": "text", "copy_to": "infer_field" } } } }
Will need the following bulk update request to ensure that infer_field
is updated correctly:
resp = client.bulk( index="test-index", operations=[ { "update": { "_id": "1" } }, { "doc": { "infer_field": "updated inference field", "source_field": "updated source field" } } ], ) print(resp)
const response = await client.bulk({ index: "test-index", operations: [ { update: { _id: "1", }, }, { doc: { infer_field: "updated inference field", source_field: "updated source field", }, }, ], }); console.log(response);
PUT test-index/_bulk {"update": {"_id": "1"}} {"doc": {"infer_field": "updated inference field", "source_field": "updated source field"}}
Notice that both the semantic_text
field and the source field are updated in the bulk request.
Limitations
editsemantic_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 can’t be defined as multi-fields of another field, nor can they contain other fields as multi-fields.