copy_to
editcopy_to
editThe 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:
resp = client.indices.create(
index="my-index-000001",
mappings={
"properties": {
"first_name": {
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
},
"full_name": {
"type": "text"
}
}
},
)
print(resp)
resp1 = client.index(
index="my-index-000001",
id="1",
document={
"first_name": "John",
"last_name": "Smith"
},
)
print(resp1)
resp2 = client.search(
index="my-index-000001",
query={
"match": {
"full_name": {
"query": "John Smith",
"operator": "and"
}
}
},
)
print(resp2)
response = client.indices.create(
index: 'my-index-000001',
body: {
mappings: {
properties: {
first_name: {
type: 'text',
copy_to: 'full_name'
},
last_name: {
type: 'text',
copy_to: 'full_name'
},
full_name: {
type: 'text'
}
}
}
}
)
puts response
response = client.index(
index: 'my-index-000001',
id: 1,
body: {
first_name: 'John',
last_name: 'Smith'
}
)
puts response
response = client.search(
index: 'my-index-000001',
body: {
query: {
match: {
full_name: {
query: 'John Smith',
operator: 'and'
}
}
}
}
)
puts response
const response = await client.indices.create({
index: "my-index-000001",
mappings: {
properties: {
first_name: {
type: "text",
copy_to: "full_name",
},
last_name: {
type: "text",
copy_to: "full_name",
},
full_name: {
type: "text",
},
},
},
});
console.log(response);
const response1 = await client.index({
index: "my-index-000001",
id: 1,
document: {
first_name: "John",
last_name: "Smith",
},
});
console.log(response1);
const response2 = await client.search({
index: "my-index-000001",
query: {
match: {
full_name: {
query: "John Smith",
operator: "and",
},
},
},
});
console.log(response2);
PUT my-index-000001
{
"mappings": {
"properties": {
"first_name": {
"type": "text",
"copy_to": "full_name"
},
"last_name": {
"type": "text",
"copy_to": "full_name"
},
"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": {
"query": "John Smith",
"operator": "and"
}
}
}
}
|
The values of the |
|
|
The |
Some important points:
- It is the field value which is copied, not the terms (which result from the analysis process).
-
The original
_sourcefield 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_1tofield_3:resp = client.indices.create( index="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" } } }, ) print(resp)const response = await client.indices.create({ index: "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", }, }, }, }); console.log(response);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:
resp = client.indices.create( index="good_example_index", mappings={ "properties": { "field_1": { "type": "text", "copy_to": [ "field_2", "field_3" ] }, "field_2": { "type": "text" }, "field_3": { "type": "text" } } }, ) print(resp)const response = await client.indices.create({ index: "good_example_index", mappings: { properties: { field_1: { type: "text", copy_to: ["field_2", "field_3"], }, field_2: { type: "text", }, field_3: { type: "text", }, }, }, }); console.log(response);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.
Dynamic mapping
editConsider 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
dynamicset totrue, a non-existent target field will be dynamically added to the index mappings. -
If
dynamicis set tofalse, the target field will not be added to the index mappings, and the value will not be copied. -
If
dynamicis set tostrict, copying to a non-existent field will result in an error.-
If the target field is nested, then
copy_tofields 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:
resp = client.indices.create( index="test_index", mappings={ "dynamic": "strict", "properties": { "description": { "properties": { "notes": { "type": "text", "copy_to": [ "description.notes_raw" ], "analyzer": "standard", "search_analyzer": "standard" }, "notes_raw": { "type": "keyword" } } } } }, ) print(resp)const response = await client.indices.create({ index: "test_index", mappings: { dynamic: "strict", properties: { description: { properties: { notes: { type: "text", copy_to: ["description.notes_raw"], analyzer: "standard", search_analyzer: "standard", }, notes_raw: { type: "keyword", }, }, }, }, }, }); console.log(response);
-
|
The In this example, |