В Elasticsearch индекс содержит схему и может иметь один или несколько шардов и реплик. Индекс Elasticsearch делится на шарды, и каждый шард является экземпляром индекса Lucene. Индексы используются для хранения документов в специальных структурах данных, соответствующих типу данных полей. Например, текстовые поля хранятся в инвертированном индексе, а числовые и геополя - в BKD-деревьях.
Вкратце, эта ошибка возникает, когда вы пытаетесь создать динамический шаблон в Elasticsearch без указания имени. Динамические шаблоны в Elasticsearch требуют уникального имени для идентификации. Чтобы решить эту проблему, вам следует убедиться, что вы указали уникальное имя при определении динамического шаблона. Также проверьте правильность синтаксиса. Если вы используете API, убедитесь, что тело запроса включает имя шаблона.
Примеры
Создание индекса
Следующий пример основан на Elasticsearch версии 5.x и выше. Будет создан индекс с двумя шардами, каждый из которых имеет одну реплику, с именем test_index1
1 2 3 4 5 6 7 8 9 10 11 12 13 | PUT /test_index1?pretty { "settings" : { "number_of_shards" : 2, "number_of_replicas" : 1 }, "mappings" : { "properties" : { "tags" : { "type" : "keyword" }, "updated_at" : { "type" : "date" } } } } |
Список индек
Индексирование документа
Добавим документ в индекс с помощью следующей команды:
1 2 3 4 5 6 7 8 | PUT test_index1/_doc/1 { "tags": [ "gsoft", "elasticsearch" ], "date": "01-01-2020" } |
Запрос к индексу
1 2 3 4 5 6 | GET test_index1/_search { "query": { "match_all": {} } } |
Запрос по нескольким индексам
Одним запросом можно выполнить поиск по нескольким индексам. Если это необработанный HTTP-запрос, имена индексов должны быть отправлены в формате с разделителями-запятыми, как показано в примере ниже, а в случае запроса через клиент на языке программирования, таком как python или Java, имена индексов должны быть отправлены в формате списка.
1 | GET test_index1,test_index2/_search |
Удаление индексов
1 | DELETE test_index1 |
Общие проблемы
- Хорошей практикой является определение настроек и маппинга индекса, поскольку если этого не сделать, Elasticsearch попытается автоматически определить тип данных полей во время индексирования. Этот автоматический процесс может иметь свои недостатки, такие как конфликты маппинга, дублирование данных и неправильные типы данных в индексе. Если поля не известны заранее, лучше использовать динамические шаблоны индексов.
- Elasticsearch поддерживает шаблоны подстановочных символов в именах индексов, что иногда помогает при запросах к нескольким индексам, но может быть и очень разрушительным. Например, можно удалить все индексы одной командой, используя следующие команды:
1 | DELETE /* |
- Чтобы отключить это, можно добавить следующие строки в elasticsearch.yml:
1action.destructive_requires_name: true
Шаблоны ElasticSearch
Шаблон в Elasticsearch относится к одной из двух следующих категорий и индексируется в Elasticsearch с помощью специальной конечной точки:
- Шаблоны индексов, которые представляют собой способ определения набора правил, включающих настройки индекса, маппинги и шаблон индекса. Шаблон применяется автоматически при создании нового индекса с соответствующим шаблоном. Шаблоны также используются для динамического применения пользовательских маппингов для полей, которые не предопределены в существующих маппингах.
- Шаблоны поиска, которые помогают определять шаблоны для поисковых запросов с помощью языка сценариев mustache. Эти шаблоны служат в качестве заполнителя для переменных, определенных в поисковых запросах.
Примеры
Создание шаблона динамического индекса
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | PUT /_template/template_1?pretty { "index_patterns": [ "logs*", "api*" ], "settings": { "number_of_shards": 2 }, "mappings": { "dynamic_templates": [ { "strings": { "match_mapping_type": "string", "mapping": { "type": "keyword" } } } ], "properties": { "host_name": { "type": "keyword" }, "created_at": { "type": "date" } } } } |
Создайте шаблон поиска
1 2 3 4 5 6 7 8 9 10 11 12 13 | POST /_scripts/search_template_1?pretty { "script": { "lang": "mustache", "source": { "query": { "match": { "description": "{{query_string}}" } } } } } |
Выполнение поискового запроса с помощью шаблона поиска
1 2 3 4 5 6 7 | GET /_search/template?pretty { "id": "search_template_1", "params": { "query_string": "hello world" } } |
Поисковый запрос по умолчанию будет выполнен по всем индексам, доступным в кластере, и может быть ограничен определенными индексами с помощью параметра index.
Примечания
Шаблон динамического индекса всегда полезен, когда вы не знаете заранее названия полей и хотите управлять их маппингом в соответствии с требованиями бизнеса.
Контекст журнала
Лог "A dynamic template must be defined with a name" Имя класса - RootObjectMapper.java. Из исходного кода Elasticsearch для тех, кто ищет более подробный контекст:
1 2 3 4 5 6 7 8 9 10 11 | List<!--?--> tmplNodes = (List<!--?-->) fieldNode; List<dynamictemplate> templates = new ArrayList<>(); for (Object tmplNode : tmplNodes) { Map<string; object=""> tmpl = (Map<string; object="">) tmplNode; if (tmpl.size() != 1) { throw new MapperParsingException("A dynamic template must be defined with a name"); } Map.Entry<string; object=""> entry = tmpl.entrySet().iterator().next(); String templateName = entry.getKey(); Map<string; object=""> templateParams = (Map<string; object="">) entry.getValue(); DynamicTemplate template = DynamicTemplate.parse(templateName; templateParams);<p></p></string;></string;></string;></string;></string;></dynamictemplate> |