Шаблоны поиска
Шаблон поиска — это сохранённый запрос, который можно запускать с различными переменными.
Если вы используете Elasticsearch в качестве поискового бэкенда, вы можете передавать пользовательский ввод из поисковой строки в качестве параметров для шаблона поиска. Это позволяет запускать запросы, не раскрывая синтаксис запросов Elasticsearch вашим пользователям.
Если вы используете Elasticsearch для собственного приложения, шаблоны поиска позволяют изменять запросы без модификации кода вашего приложения.
Создать шаблон поиска
Чтобы создать или обновить шаблон поиска, используйте API для создания или обновления сохранённого скрипта.
Запрос source поддерживает те же параметры, что и тело запроса API поиска. source также поддерживает переменные Mustache, обычно заключённые в двойные фигурные скобки: {{my-var}}. При выполнении запроса с шаблоном Elasticsearch заменяет эти переменные значениями из params.
Шаблоны поиска должны использовать lang типа mustache.
Следующий запрос создаёт шаблон поиска с id типа my-search-template.
PUT _scripts/my-search-template
{
"script": {
"lang": "mustache",
"source": {
"query": {
"match": {
"message": "{{query_string}}"
}
},
"from": "{{from}}",
"size": "{{size}}"
}
}
} Elasticsearch сохраняет шаблоны поиска как скрипты Mustache в состоянии кластера. Elasticsearch компилирует шаблоны поиска в контексте скрипта template. Параметры, ограничивающие или отключающие скрипты, также влияют на шаблоны поиска.
Проверить шаблон поиска
Для проверки шаблона с различными params используйте API для рендеринга шаблона поиска.
POST _render/template
{
"id": "my-search-template",
"params": {
"query_string": "hello world",
"from": 20,
"size": 10
}
} При рендеринге шаблон выводит тело запроса для API поиска.
{
"template_output": {
"query": {
"match": {
"message": "hello world"
}
},
"from": "20",
"size": "10"
}
} Вы также можете использовать API для проверки встроенных шаблонов.
POST _render/template
{
"source": {
"query": {
"match": {
"message": "{{query_string}}"
}
},
"from": "{{from}}",
"size": "{{size}}"
},
"params": {
"query_string": "hello world",
"from": 20,
"size": 10
}
} Запуск запроса с шаблоном поиска
Чтобы запустить поиск с шаблоном поиска, используйте API шаблона поиска. Вы можете указывать различные params с каждым запросом.
GET my-index/_search/template
{
"id": "my-search-template",
"params": {
"query_string": "hello world",
"from": 0,
"size": 10
}
} Ответ использует те же свойства, что и ответ API поиска.
{
"took": 36,
"timed_out": false,
"_shards": {
"total": 1,
"successful": 1,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 1,
"relation": "eq"
},
"max_score": 0.5753642,
"hits": [
{
"_index": "my-index",
"_type": "_doc",
"_id": "1",
"_score": 0.5753642,
"_source": {
"message": "hello world"
}
}
]
}
} Запуск нескольких запросов с шаблонами поиска
Чтобы запустить несколько запросов с шаблонами поиска одним запросом, используйте API для нескольких запросов с шаблонами поиска. Такие запросы часто имеют меньшую нагрузку и большую скорость, чем несколько отдельных запросов.
GET my-index/_msearch/template
{ }
{ "id": "my-search-template", "params": { "query_string": "hello world", "from": 0, "size": 10 }}
{ }
{ "id": "my-other-search-template", "params": { "query_type": "match_all" }} Получение шаблонов поиска
Чтобы получить шаблон поиска, используйте API для получения сохранённого скрипта.
GET _scripts/my-search-template
Чтобы получить список всех шаблонов поиска и других сохранённых скриптов, используйте API состояния кластера.
GET _cluster/state/metadata?pretty&filter_path=metadata.stored_scripts
Удаление шаблона поиска
Чтобы удалить шаблон поиска, используйте API для удаления сохранённого скрипта.
DELETE _scripts/my-search-template
Установка значений по умолчанию
Для установки значения по умолчанию для переменной используйте следующий синтаксис:
{{my-var}}{{^my-var}}default value{{/my-var}} Если шаблон поиска не указывает значение в своём params, поиск использует значение по умолчанию вместо него. Например, следующий шаблон устанавливает значения по умолчанию для from и size.
POST _render/template
{
"source": {
"query": {
"match": {
"message": "{{query_string}}"
}
},
"from": "{{from}}{{^from}}0{{/from}}",
"size": "{{size}}{{^size}}10{{/size}}"
},
"params": {
"query_string": "hello world"
}
} Кодирование строк в URL
Используйте функцию {{#url}} для кодирования строки в URL.
POST _render/template
{
"source": {
"query": {
"term": {
"url.full": "{{#url}}{{host}}/{{page}}{{/url}}"
}
}
},
"params": {
"host": "http://example.com",
"page": "hello-world"
}
} Шаблон рендерится как:
{
"template_output": {
"query": {
"term": {
"url.full": "http%3A%2F%2Fexample.com%2Fhello-world"
}
}
}
} Конкатенация значений
Используйте функцию {{#join}} для конкатенации значений массива в строку, разделённую запятыми. Например, следующий шаблон конкатенирует два адреса электронной почты.
POST _render/template
{
"source": {
"query": {
"match": {
"user.group.emails": "{{#join}}emails{{/join}}"
}
}
},
"params": {
"emails": [ "user1@example.com", "user_one@example.com" ]
}
} Шаблон рендерится как:
{
"template_output": {
"query": {
"match": {
"user.group.emails": "user1@example.com,user_one@example.com"
}
}
}
} Вы также можете указать пользовательский разделитель.
POST _render/template
{
"source": {
"query": {
"range": {
"user.effective.date": {
"gte": "{{date.min}}",
"lte": "{{date.max}}",
"format": "{{#join delimiter='||'}}date.formats{{/join delimiter='||'}}"
}
}
}
},
"params": {
"date": {
"min": "2098",
"max": "06/05/2099",
"formats": ["dd/MM/yyyy", "yyyy"]
}
}
} Шаблон рендерится как:
{
"template_output": {
"query": {
"range": {
"user.effective.date": {
"gte": "2098",
"lte": "06/05/2099",
"format": "dd/MM/yyyy||yyyy"
}
}
}
}
} Преобразование в JSON
Используйте функцию {{#toJson}} для преобразования значения переменной в её представление JSON.
Например, следующий шаблон использует {{#toJson}} для передачи массива. Для обеспечения валидности тела запроса в формате JSON, source записано в строчном формате.
POST _render/template
{
"source": "{ \"query\": { \"terms\": { \"tags\": {{#toJson}}tags{{/toJson}} }}}",
"params": {
"tags": [
"prod",
"es01"
]
}
} Шаблон рендерится как:
{
"template_output": {
"query": {
"terms": {
"tags": [
"prod",
"es01"
]
}
}
}
} Вы также можете использовать {{#toJson}} для передачи объектов.
POST _render/template
{
"source": "{ \"query\": {{#toJson}}my_query{{/toJson}} }",
"params": {
"my_query": {
"match_all": { }
}
}
} Шаблон рендерится как:
{
"template_output" : {
"query" : {
"match_all" : { }
}
}
} Вы также можете передавать массив объектов.
POST _render/template
{
"source": "{ \"query\": { \"bool\": { \"must\": {{#toJson}}clauses{{/toJson}} }}}",
"params": {
"clauses": [
{
"term": {
"user.id": "kimchy"
}
},
{
"term": {
"url.domain": "example.com"
}
}
]
}
} Шаблон рендерится как:
{
"template_output": {
"query": {
"bool": {
"must": [
{
"term": {
"user.id": "kimchy"
}
},
{
"term": {
"url.domain": "example.com"
}
}
]
}
}
}
} Использование условий
Для создания условий if используйте следующий синтаксис:
{{#condition}}content{{/condition}} Если переменная условия равна true, Elasticsearch отображает её содержимое. Например, следующий шаблон ищет данные за прошлый год, если year_scope равно true.
POST _render/template
{
"source": "{ \"query\": { \"bool\": { \"filter\": [ {{#year_scope}} { \"range\": { \"@timestamp\": { \"gte\": \"now-1y/d\", \"lt\": \"now/d\" } } }, {{/year_scope}} { \"term\": { \"user.id\": \"{{user_id}}\" }}]}}}",
"params": {
"year_scope": true,
"user_id": "kimchy"
}
} Шаблон рендерится как:
{
"template_output" : {
"query" : {
"bool" : {
"filter" : [
{
"range" : {
"@timestamp" : {
"gte" : "now-1y/d",
"lt" : "now/d"
}
}
},
{
"term" : {
"user.id" : "kimchy"
}
}
]
}
}
}
} Если year_scope равно false, шаблон ищет данные за любой период времени.
POST _render/template
{
"source": "{ \"query\": { \"bool\": { \"filter\": [ {{#year_scope}} { \"range\": { \"@timestamp\": { \"gte\": \"now-1y/d\", \"lt\": \"now/d\" } } }, {{/year_scope}} { \"term\": { \"user.id\": \"{{user_id}}\" }}]}}}",
"params": {
"year_scope": false,
"user_id": "kimchy"
}
} Шаблон рендерится как:
{
"template_output" : {
"query" : {
"bool" : {
"filter" : [
{
"term" : {
"user.id" : "kimchy"
}
}
]
}
}
}
} Для создания условий if-else используйте следующий синтаксис:
{{#condition}}if content{{/condition}} {{^condition}}else content{{/condition}} Например, следующий шаблон ищет данные за прошлый год, если year_scope равно true. В противном случае он ищет данные за прошлый день.
POST _render/template
{
"source": "{ \"query\": { \"bool\": { \"filter\": [ { \"range\": { \"@timestamp\": { \"gte\": {{#year_scope}} \"now-1y/d\" {{/year_scope}} {{^year_scope}} \"now-1d/d\" {{/year_scope}} , \"lt\": \"now/d\" }}}, { \"term\": { \"user.id\": \"{{user_id}}\" }}]}}}",
"params": {
"year_scope": true,
"user_id": "kimchy"
}
}
© 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/search-template.html