Динамические шаблоны
Динамические шаблоны предоставляют больший контроль над тем, как Elasticsearch отображает ваши данные, выходя за рамки стандартных правил динамического отображения полей. Вы активируете динамическое отображение, установив параметр dynamic в значение true или runtime. После этого вы можете использовать динамические шаблоны для определения пользовательских отображений, которые могут применяться к динамически добавляемым полям на основе соответствия условиям:
-
match_mapping_typeработает с типом данных, который обнаруживает Elasticsearch -
matchиunmatchиспользуют шаблон для сопоставления с именем поля -
path_matchиpath_unmatchработают с полным составным путем к полю - Если динамический шаблон не определяет
match_mapping_type,matchилиpath_match, он не будет соответствовать ни одному полю. Тем не менее, вы можете всё равно сослаться на шаблон по имени в разделеdynamic_templatesзапроса поточной индексации.
Используйте {name} и {dynamic_type} переменные шаблона в спецификации отображения в качестве заглушек.
Динамическое отображение полей добавляется только тогда, когда поле содержит конкретное значение. Elasticsearch не добавляет динамическое отображение поля, когда поле содержит null или пустой массив. Если используется опция null_value в dynamic_template, она будет применена только после индексации первого документа с конкретным значением для поля.
Динамические шаблоны задаются в виде массива именованных объектов:
"dynamic_templates": [
{
"my_template_name": {
... match conditions ...
"mapping": { ... }
}
},
...
] | Имя шаблона может быть любым строковым значением. | |
| Условия соответствия могут включать любые из : | |
| Отображение, которое должно использоваться для сопоставленного поля. |
Проверка динамических шаблонов
Если предоставленное отображение содержит фрагмент некорректного отображения, возвращается ошибка проверки. Проверка происходит при применении динамического шаблона во время индексации и, в большинстве случаев, при обновлении динамического шаблона. Предоставление некорректного фрагмента отображения может привести к сбою обновления или проверки динамического шаблона в определенных условиях:
- Если не указан
match_mapping_type, но шаблон действителен для по крайней мере одного предопределенного типа отображения, фрагмент отображения считается корректным. Однако, ошибка проверки возвращается во время индексации, если поле, соответствующее шаблону, проиндексировано как другой тип. Например, настройка динамического шаблона безmatch_mapping_typeсчитается действительной для строкового типа, но если поле, соответствующее динамическому шаблону, проиндексировано как целое число, возвращается ошибка проверки во время индексации. Рекомендуется настроитьmatch_mapping_typeдо ожидаемого типа JSON или настроить необходимоеtypeв фрагменте отображения. - Если используется заполнитель
{name}в фрагменте отображения, проверка пропускается при обновлении динамического шаблона. Это связано с тем, что имя поля неизвестно в этот момент. Вместо этого проверка выполняется при применении шаблона во время индексации.
Шаблоны обрабатываются в порядке — первый соответствующий шаблон выигрывает. При добавлении новых динамических шаблонов через API обновления отображения все существующие шаблоны перезаписываются. Это позволяет переупорядочивать или удалять динамические шаблоны после их первоначального добавления.
Отображение полей runtime в динамическом шаблоне
Если вы хотите, чтобы Elasticsearch динамически отображал новые поля определенного типа как поля runtime, установите "dynamic":"runtime" в отображениях индекса. Эти поля не индексируются и загружаются из _source во время запроса.
В качестве альтернативы, вы можете использовать стандартные правила динамического отображения, а затем создать динамические шаблоны для отображения определенных полей как полей runtime. Установите "dynamic":"true" в вашем отображении индекса, а затем создайте динамический шаблон для отображения новых полей определенного типа как полей runtime.
Предположим, у вас есть данные, где каждое поле начинается с ip_. Основываясь на правилах динамического отображения, Elasticsearch отображает любые string, которые проходят проверку numeric, как float или long. Однако, вы можете создать динамический шаблон, отображающий новые строки как поля runtime типа ip.
Следующий запрос определяет динамический шаблон с именем strings_as_ip. Когда Elasticsearch обнаруживает новые поля string, соответствующие шаблону ip*, он отображает эти поля как поля runtime типа ip. Поскольку поля ip не отображаются динамически, вы можете использовать этот шаблон с "dynamic":"true" или "dynamic":"runtime".
PUT my-index-000001/
{
"mappings": {
"dynamic_templates": [
{
"strings_as_ip": {
"match_mapping_type": "string",
"match": "ip*",
"runtime": {
"type": "ip"
}
}
}
]
}
} См. пример о том, как использовать динамические шаблоны для отображения полей string как индексированных полей или полей runtime.
match_mapping_type
Тип данных match_mapping_type определяется парсером JSON. Поскольку JSON не различает long от integer или double от float, любое проанализированное число с плавающей запятой считается типом данных JSON double, а любое проанализированное целое число считается типом данных long.
При динамических сопоставлениях Elasticsearch всегда выбирает тип данных с большей емкостью. Исключение составляет float, которое требует меньшего объёма памяти, чем double и достаточно точно для большинства приложений. Динамические поля не поддерживают float, поэтому "dynamic":"runtime" использует double.
Elasticsearch автоматически определяет следующие типы данных:
Тип данных Elasticsearch | ||
Тип данных JSON |
|
|
| Поле не добавлено | Поле не добавлено |
|
|
|
|
|
|
|
|
|
|
| Поле не добавлено |
| Зависит от первого не- | Зависит от первого не- |
|
|
|
|
|
|
|
|
|
Используйте символ подстановки (*) для соответствия всем типам данных.
Например, если мы хотим сопоставить все целочисленные поля как integer вместо long, и все поля string как text и keyword, мы можем использовать следующий шаблон:
PUT my-index-000001
{
"mappings": {
"dynamic_templates": [
{
"integers": {
"match_mapping_type": "long",
"mapping": {
"type": "integer"
}
}
},
{
"strings": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"fields": {
"raw": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
]
}
}
PUT my-index-000001/_doc/1
{
"my_integer": 5,
"my_string": "Some string"
} | Поле | |
| Поле |
match и unmatch
Параметр match использует шаблон для сопоставления с именем поля, а unmatch использует шаблон для исключения полей, сопоставленных match.
Параметр match_pattern настраивает поведение параметра match для поддержки полного соответствия с использованием регулярных выражений Java на имени поля вместо простых подстановочных знаков. Например:
"match_pattern": "regex", "match": "^profit_\d+$"
Следующий пример сопоставляет все поля string, имена которых начинаются с long_ (кроме тех, которые заканчиваются на _text), и сопоставляет их как поля long:
PUT my-index-000001
{
"mappings": {
"dynamic_templates": [
{
"longs_as_strings": {
"match_mapping_type": "string",
"match": "long_*",
"unmatch": "*_text",
"mapping": {
"type": "long"
}
}
}
]
}
}
PUT my-index-000001/_doc/1
{
"long_num": "5",
"long_text": "foo"
} | Поле | |
| Поле |
path_match и path_unmatch
Параметры path_match и path_unmatch работают так же, как и match и unmatch, но работают с полным составным именем поля, а не только с последним именем, например, some_object.*.some_field.
Этот пример копирует значения любых полей в объекте name в поле верхнего уровня full_name, за исключением поля middle:
PUT my-index-000001
{
"mappings": {
"dynamic_templates": [
{
"full_name": {
"path_match": "name.*",
"path_unmatch": "*.middle",
"mapping": {
"type": "text",
"copy_to": "full_name"
}
}
}
]
}
}
PUT my-index-000001/_doc/1
{
"name": {
"first": "John",
"middle": "Winston",
"last": "Lennon"
}
} Обратите внимание, что параметры path_match и path_unmatch соответствуют путям объектов помимо самих полей. Например, индексирование следующего документа приведёт к ошибке, поскольку настройка path_match также сопоставляется с полем объекта name.title, которое не может быть сопоставлено как строка:
PUT my-index-000001/_doc/2
{
"name": {
"first": "Paul",
"last": "McCartney",
"title": {
"value": "Sir",
"category": "order of chivalry"
}
}
} Переменные шаблона
Подстановки {name} и {dynamic_type} заменяются в mapping именем поля и обнаруженным динамическим типом. Следующий пример назначает всем строковым полям analyzer с тем же именем, что и поле, и отключает doc_values для всех полей, не являющихся строками:
PUT my-index-000001
{
"mappings": {
"dynamic_templates": [
{
"named_analyzers": {
"match_mapping_type": "string",
"match": "*",
"mapping": {
"type": "text",
"analyzer": "{name}"
}
}
},
{
"no_doc_values": {
"match_mapping_type":"*",
"mapping": {
"type": "{dynamic_type}",
"doc_values": false
}
}
}
]
}
}
PUT my-index-000001/_doc/1
{
"english": "Some English text",
"count": 5
} | Поле | |
| Поле |
Примеры динамических шаблонов
Ниже приведены примеры потенциально полезных динамических шаблонов:
Структурированный поиск
При установке "dynamic":"true" Elasticsearch будет отображать строковые поля как поле типа text с подполем keyword. Если вы индексируете только структурированное содержимое и не заинтересованы в поиске по полному тексту, вы можете настроить Elasticsearch на отображение ваших полей только как поля типа keyword. Однако вам необходимо искать по точно такому же значению, которое было проиндексировано для поиска по этим полям.
PUT my-index-000001
{
"mappings": {
"dynamic_templates": [
{
"strings_as_keywords": {
"match_mapping_type": "string",
"mapping": {
"type": "keyword"
}
}
}
]
}
}
text-только отображения для строк
В отличие от предыдущего примера, если вас интересует только поиск по полному тексту в строковых полях и вы не планируете выполнять агрегации, сортировку или точные поиски, вы можете указать Elasticsearch отображать строки как text:
PUT my-index-000001
{
"mappings": {
"dynamic_templates": [
{
"strings_as_text": {
"match_mapping_type": "string",
"mapping": {
"type": "text"
}
}
}
]
}
} В качестве альтернативы вы можете создать динамический шаблон для отображения ваших строковых полей как полей типа keyword в разделе отображения во время выполнения. Когда Elasticsearch обнаруживает новые поля типа string, эти поля будут созданы как поля типа keyword во время выполнения.
Хотя ваши поля string не будут проиндексированы, их значения хранятся в _source и могут использоваться в запросах поиска, агрегациях, фильтрации и сортировке.
Например, следующий запрос создает динамический шаблон для отображения полей string как полей типа keyword во время выполнения. Хотя определение runtime пустое, новые поля string будут отображаться как поля keyword во время выполнения, основываясь на правилах динамического отображения, используемых Elasticsearch для добавления типов полей в отображение. Любое поле string, которое не проходит проверку на дату или число, автоматически отображается как поле типа keyword:
PUT my-index-000001
{
"mappings": {
"dynamic_templates": [
{
"strings_as_keywords": {
"match_mapping_type": "string",
"runtime": {}
}
}
]
}
} Вы индексируете простой документ:
PUT my-index-000001/_doc/1
{
"english": "Some English text",
"count": 5
} При просмотре отображения вы увидите, что поле english является полем типа keyword во время выполнения:
GET my-index-000001/_mapping
{
"my-index-000001" : {
"mappings" : {
"dynamic_templates" : [
{
"strings_as_keywords" : {
"match_mapping_type" : "string",
"runtime" : { }
}
}
],
"runtime" : {
"english" : {
"type" : "keyword"
}
},
"properties" : {
"count" : {
"type" : "long"
}
}
}
}
} Отключение норм
Нормы — это факторы оценки на этапе индексирования. Если вам не важна оценка, например, если вы никогда не сортируете документы по оценке, вы можете отключить хранение этих факторов оценки в индексе и сэкономить место.
PUT my-index-000001
{
"mappings": {
"dynamic_templates": [
{
"strings_as_keywords": {
"match_mapping_type": "string",
"mapping": {
"type": "text",
"norms": false,
"fields": {
"keyword": {
"type": "keyword",
"ignore_above": 256
}
}
}
}
}
]
}
} Подполе keyword в этом шаблоне присутствует для согласованности с правилами динамического отображения по умолчанию. Конечно, если вам они не нужны, потому что вам не требуется точный поиск или агрегация по этому полю, вы можете удалить его, как описано в предыдущем разделе.
Временные ряды
При анализе временных рядов с помощью Elasticsearch часто встречаются многочисленные числовые поля, по которым часто выполняется агрегация, но никогда не выполняется фильтрация. В таком случае вы можете отключить индексирование этих полей, чтобы сэкономить место на диске и, возможно, повысить скорость индексирования:
PUT my-index-000001
{
"mappings": {
"dynamic_templates": [
{
"unindexed_longs": {
"match_mapping_type": "long",
"mapping": {
"type": "long",
"index": false
}
}
},
{
"unindexed_doubles": {
"match_mapping_type": "double",
"mapping": {
"type": "float",
"index": false
}
}
}
]
}
} | Так же, как и правила динамического отображения по умолчанию, числа с плавающей запятой отображаются как числа с плавающей запятой одинарной точности, что обычно достаточно точно, но требует вдвое меньше места на диске. |
© 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/7.17/dynamic-templates.html