Spec-Zone.ru › Elasticsearch 8
›Elasticsearch Guide [8.17] ›Картирование ›Параметры карты

copy_to

Параметр copy_to позволяет копировать значения нескольких полей в групповое поле, которое затем можно использовать в запросах как одно поле.

Если вы часто ищете по нескольким полям, вы можете ускорить поиск, используя copy_to для поиска по меньшему количеству полей. См. Поиск по минимальному количеству полей.

Например, поля first_name и last_name можно скопировать в поле full_name следующим образом:

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"
      }
    }
  }
}

Значения полей first_name и last_name копируются в поле full_name.

Поля first_name и last_name всё ещё можно использовать для поиска имени и фамилии соответственно, но поле full_name можно использовать для поиска и имени, и фамилии.

Некоторые важные моменты:

  • Копируется значение поля, а не термины (которые являются результатом процесса анализа).
  • Исходное поле _source не будет изменено, чтобы отобразить скопированные значения.
  • Одно и то же значение можно скопировать в несколько полей с помощью "copy_to": [ "field_1", "field_2" ]
  • Нельзя выполнить рекурсивную копию, используя промежуточные поля. Следующая конфигурация не скопирует данные из field_1 в field_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"
          }
        }
      }
    }

    Вместо этого скопируйте в несколько полей из исходного поля:

    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 не поддерживается для типов полей, где значения представляют собой объекты, например, date_range.

Динамическое картирование

Рассмотрите следующие моменты при использовании copy_to с динамическим картированием:

  • Если целевого поля нет в картах индекса, применяется обычное поведение динамического картирования. По умолчанию, с dynamic установленным на значение true, не существующее целевое поле будет динамически добавлено в карты индекса.
  • Если dynamic установлено на значение false, целевое поле не будет добавлено в карты индекса, и значение не будет скопировано.
  • Если dynamic установлено на значение strict, копирование в не существующее поле приведет к ошибке.

    • Если целевое поле вложено, тогда поля copy_to должны указывать полный путь к вложенному полю. Пропуск полного пути приведет к ошибке strict_dynamic_mapping_exception. Используйте "copy_to": ["parent_field.child_field"] для правильного указания вложенного поля.

      Например:

      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);
      PUT /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"
                }
              }
            }
          }
        }
      }

Поле notes копируется в поле notes_raw. Указание только notes_raw вместо description.notes_raw приведет к ошибке strict_dynamic_mapping_exception.

В этом примере notes_raw не определено в корне карты, а под полем description. Без полного пути Elasticsearch интерпретирует целевое поле copy_to как поле корневого уровня, а не как вложенное поле под полем description.

© 2023-2025 Elasticsearch
As of September 2024, Elasticsearch is available under a choice of three licenses: the Server Side Public License (SSPL), the Elastic License, or the AGPLv3 (OSI approved).
Elasticsearch and the Elasticsearch logo are trademarks of Elasticsearch B.V., registered in the U.S. and in other countries.
https://www.elastic.co/guide/en/elasticsearch/reference/8.17/copy-to.html

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API