copy_to
The copy_to
parameter allows you to copy the values of multiple fields into a group field, which can then be queried as a single field.
If you often search multiple fields, you can improve search speeds by using copy_to
to search fewer fields. See Search as few fields as possible.
For example, the first_name
and last_name
fields can be copied to the full_name
field as follows:
PUT my-index-000001
{
"mappings": {
"properties": {
"first_name": {
"type": "text",
"copy_to": "full_name" 1
},
"last_name": {
"type": "text",
"copy_to": "full_name" 1
},
"full_name": {
"type": "text"
}
}
}
}
PUT my-index-000001/_doc/1
{
"first_name": "John",
"last_name": "Smith"
}
GET my-index-000001/_search
{
"query": {
"match": {
"full_name": { 2
"query": "John Smith",
"operator": "and"
}
}
}
}
- The values of the
first_name
andlast_name
fields are copied to thefull_name
field. - The
first_name
andlast_name
fields can still be queried for the first name and last name respectively, but thefull_name
field can be queried for both first and last names.
Some important points:
It is the field value which is copied, not the terms (which result from the analysis process).
The original
_source
field will not be modified to show the copied values.The same value can be copied to multiple fields, with
"copy_to": [ "field_1", "field_2" ]
You cannot copy recursively using intermediary fields. The following configuration will not copy data from
field_1
tofield_3
:PUT bad_example_index
{ "mappings": { "properties": { "field_1": { "type": "text", "copy_to": "field_2" }, "field_2": { "type": "text", "copy_to": "field_3" }, "field_3": { "type": "text" } } } }
Instead, copy to multiple fields from the source field:
PUT good_example_index
{ "mappings": { "properties": { "field_1": { "type": "text", "copy_to": ["field_2", "field_3"] }, "field_2": { "type": "text" }, "field_3": { "type": "text" } } } }
copy_to
is not supported for field types where values take the form of objects, e.g. date_range
.
Consider the following points when using copy_to
with dynamic mappings:
If the target field does not exist in the index mappings, the usual dynamic mapping behavior applies. By default, with
dynamic
set totrue
, a non-existent target field will be dynamically added to the index mappings.If
dynamic
is set tofalse
, the target field will not be added to the index mappings, and the value will not be copied.If
dynamic
is set tostrict
, copying to a non-existent field will result in an error.If the target field is nested, then
copy_to
fields must specify the full path to the nested field. Omitting the full path will lead to astrict_dynamic_mapping_exception
. Use"copy_to": ["parent_field.child_field"]
to correctly target a nested field.For example:
PUT /test_index
{ "mappings": { "dynamic": "strict", "properties": { "description": { "properties": { "notes": { "type": "text", "copy_to": [ "description.notes_raw"], 1 "analyzer": "standard", "search_analyzer": "standard" }, "notes_raw": { "type": "keyword" } } } } } }
- The
notes
field is copied to thenotes_raw
field. Targetingnotes_raw
alone instead ofdescription.notes_raw
would lead to astrict_dynamic_mapping_exception
.In this example,notes_raw
is not defined at the root of the mapping, but under thedescription
field. Without the fully qualified path, Elasticsearch would interpret thecopy_to
target as a root-level field, not as a nested field underdescription
.
- The