WARNING: Version 2.4 of Elasticsearch has passed its EOL date.
This documentation is no longer being maintained and may be removed. If you are running this version, we strongly advise you to upgrade. For the latest information, see the current release documentation.
Search Template
editSearch Template
editThe /_search/template
endpoint allows to use the mustache language to pre render search requests,
before they are executed and fill existing templates with template parameters.
GET /_search/template { "inline" : { "query": { "match" : { "{{my_field}}" : "{{my_value}}" } }, "size" : "{{my_size}}" }, "params" : { "my_field" : "foo", "my_value" : "bar", "my_size" : 5 } }
For more information on how Mustache templating and what kind of templating you can do with it check out the online documentation of the mustache project.
The mustache language is implemented in elasticsearch as a sandboxed scripting language, hence it obeys settings that may be used to enable or disable scripts per language, source and operation as described in scripting docs
More template examples
editFilling in a query string with a single value
editGET /_search/template { "inline": { "query": { "match": { "title": "{{query_string}}" } } }, "params": { "query_string": "search for these words" } }
Passing an array of strings
editGET /_search/template { "inline": { "query": { "terms": { "status": [ "{{#status}}", "{{.}}", "{{/status}}" ] } } }, "params": { "status": [ "pending", "published" ] } }
which is rendered as:
Alternatively, you can flatten the status
parameter into a string which is
passed in unescaped (using {{{ }}}
) as follows:
GET /_search/template { "inline": "{\"query\": {\"terms\": {\"status\": [ {{{status}}} ]}}}", "params": { "status": "\"pending\", \"published\"" } }
which is rendered as:
{ "query": { "terms": { "status": [ "pending", "published" ] } } }
Concatenating array of values
editThe {{#join}}array{{/join}}
function can be used to concatenate the
values of an array as a comma delimited string:
GET /_search/template { "inline": { "query": { "match": { "emails": "{{#join}}emails{{/join}}" } } }, "params": { "emails": [ "username@email.com", "lastname@email.com" ] } }
which is rendered as:
{ "query" : { "match" : { "emails" : "username@email.com,lastname@email.com" } } }
The function also accepts a custom delimiter:
GET /_search/template { "inline": { "query": { "range": { "born": { "gte" : "{{date.min}}", "lte" : "{{date.max}}", "format": "{{#join delimiter='||'}}date.formats{{/join delimiter='||'}}" } } } }, "params": { "date": { "min": "2016", "max": "31/12/2017", "formats": ["dd/MM/yyyy", "yyyy"] } } }
which is rendered as:
{ "query" : { "range" : { "born" : { "gte" : "2016", "lte" : "31/12/2017", "format" : "dd/MM/yyyy||yyyy" } } } }
Default values
editA default value is written as {{var}}{{^var}}default{{/var}}
for instance:
{ "inline": { "query": { "range": { "line_no": { "gte": "{{start}}", "lte": "{{end}}{{^end}}20{{/end}}" } } } }, "params": { ... } }
When params
is { "start": 10, "end": 15 }
this query would be rendered as:
{ "range": { "line_no": { "gte": "10", "lte": "15" } } }
But when params
is { "start": 10 }
this query would use the default value
for end
:
{ "range": { "line_no": { "gte": "10", "lte": "20" } } }
Converting parameters to JSON
editThe {{#toJson}}parameter{{/toJson}}
function can be used to convert parameters
like maps and array to their JSON representation:
{ "inline": "{\"query\":{\"bool\":{\"must\": {{#toJson}}clauses{{/toJson}} }}}", "params": { "clauses": [ { "term": "foo" }, { "term": "bar" } ] } }
which is rendered as:
{ "query" : { "bool" : { "must" : [ { "term" : "foo" }, { "term" : "bar" } ] } } }
Conditional clauses
editConditional clauses cannot be expressed using the JSON form of the template.
Instead, the template must be passed as a string. For instance, let’s say
we wanted to run a match
query on the line
field, and optionally wanted
to filter by line numbers, where start
and end
are optional.
The params
would look like:
We could write the query as:
{ "query": { "bool": { "must": { "match": { "line": "{{text}}" } }, "filter": { {{#line_no}} "range": { "line_no": { {{#start}} "gte": "{{start}}" {{#end}},{{/end}} {{/start}} {{#end}} "lte": "{{end}}" {{/end}} } } {{/line_no}} } } } }
Fill in the value of param |
|
Include the |
|
Include the |
|
Fill in the value of param |
|
Add a comma after the |
|
Include the |
|
Fill in the value of param |
As written above, this template is not valid JSON because it includes the
section markers like {{#line_no}}
. For this reason, the template should
either be stored in a file (see Pre-registered template) or, when used
via the REST API, should be written as a string:
"inline": "{\"query\":{\"bool\":{\"must\":{\"match\":{\"line\":\"{{text}}\"}},\"filter\":{{{#line_no}}\"range\":{\"line_no\":{{{#start}}\"gte\":\"{{start}}\"{{#end}},{{/end}}{{/start}}{{#end}}\"lte\":\"{{end}}\"{{/end}}}}{{/line_no}}}}}}"
Pre-registered template
editYou can register search templates by storing it in the config/scripts
directory, in a file using the .mustache
extension.
In order to execute the stored template, reference it by it’s name under the template
key:
GET /_search/template { "file": "storedTemplate", "params": { "query_string": "search for these words" } }
You can also register search templates by storing it in the elasticsearch cluster in a special index named .scripts
.
There are REST APIs to manage these indexed templates.
POST /_search/template/<templatename> { "template": { "query": { "match": { "title": "{{query_string}}" } } } }
This template can be retrieved by
GET /_search/template/<templatename>
which is rendered as:
{ "template": { "query": { "match": { "title": "{{query_string}}" } } } }
This template can be deleted by
DELETE /_search/template/<templatename>
To use an indexed template at search time use:
GET /_search/template { "id": "templateName", "params": { "query_string": "search for these words" } }
Validating templates
editA template can be rendered in a response with given parameters using
GET /_render/template { "inline": { "query": { "terms": { "status": [ "{{#status}}", "{{.}}", "{{/status}}" ] } } }, "params": { "status": [ "pending", "published" ] } }
This call will return the rendered template:
File and indexed templates can also be rendered by replacing inline
with
file
or id
respectively. For example, to render a file template
GET /_render/template { "file": "my_template", "params": { "status": [ "pending", "published" ] } }
Pre-registered templates can also be rendered using
GET /_render/template/<template_name> { "params": { "..." } }