372 lines
8.6 KiB
Plaintext
372 lines
8.6 KiB
Plaintext
[[search-template]]
|
|
== Search Template
|
|
|
|
The `/_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.
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
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 http://mustache.github.io/mustache.5.html[online
|
|
documentation of the mustache project].
|
|
|
|
NOTE: 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
|
|
<<enable-dynamic-scripting, scripting docs>>
|
|
|
|
[float]
|
|
==== More template examples
|
|
|
|
[float]
|
|
===== Filling in a query string with a single value
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
GET /_search/template
|
|
{
|
|
"inline": {
|
|
"query": {
|
|
"match": {
|
|
"title": "{{query_string}}"
|
|
}
|
|
}
|
|
},
|
|
"params": {
|
|
"query_string": "search for these words"
|
|
}
|
|
}
|
|
------------------------------------------
|
|
|
|
[float]
|
|
===== Passing an array of strings
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
GET /_search/template
|
|
{
|
|
"inline": {
|
|
"query": {
|
|
"terms": {
|
|
"status": [
|
|
"{{#status}}",
|
|
"{{.}}",
|
|
"{{/status}}"
|
|
]
|
|
}
|
|
}
|
|
},
|
|
"params": {
|
|
"status": [ "pending", "published" ]
|
|
}
|
|
}
|
|
------------------------------------------
|
|
|
|
which is rendered as:
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
{
|
|
"query": {
|
|
"terms": {
|
|
"status": [ "pending", "published" ]
|
|
}
|
|
}
|
|
------------------------------------------
|
|
|
|
[float]
|
|
===== Default values
|
|
|
|
A default value is written as `{{var}}{{^var}}default{{/var}}` for instance:
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
{
|
|
"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:
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
{
|
|
"range": {
|
|
"line_no": {
|
|
"gte": "10",
|
|
"lte": "15"
|
|
}
|
|
}
|
|
}
|
|
------------------------------------------
|
|
|
|
But when `params` is `{ "start": 10 }` this query would use the default value
|
|
for `end`:
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
{
|
|
"range": {
|
|
"line_no": {
|
|
"gte": "10",
|
|
"lte": "20"
|
|
}
|
|
}
|
|
}
|
|
------------------------------------------
|
|
|
|
[float]
|
|
===== Conditional clauses
|
|
|
|
Conditional 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:
|
|
[source,js]
|
|
------------------------------------------
|
|
{
|
|
"params": {
|
|
"text": "words to search for",
|
|
"line_no": { <1>
|
|
"start": 10, <1>
|
|
"end": 20 <1>
|
|
}
|
|
}
|
|
}
|
|
------------------------------------------
|
|
<1> All three of these elements are optional.
|
|
|
|
We could write the query as:
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
{
|
|
"query": {
|
|
"bool": {
|
|
"must": {
|
|
"match": {
|
|
"line": "{{text}}" <1>
|
|
}
|
|
},
|
|
"filter": {
|
|
{{#line_no}} <2>
|
|
"range": {
|
|
"line_no": {
|
|
{{#start}} <3>
|
|
"gte": "{{start}}" <4>
|
|
{{#end}},{{/end}} <5>
|
|
{{/start}} <3>
|
|
{{#end}} <6>
|
|
"lte": "{{end}}" <7>
|
|
{{/end}} <6>
|
|
}
|
|
}
|
|
{{/line_no}} <2>
|
|
}
|
|
}
|
|
}
|
|
}
|
|
------------------------------------------
|
|
<1> Fill in the value of param `text`
|
|
<2> Include the `range` filter only if `line_no` is specified
|
|
<3> Include the `gte` clause only if `line_no.start` is specified
|
|
<4> Fill in the value of param `line_no.start`
|
|
<5> Add a comma after the `gte` clause only if `line_no.start`
|
|
AND `line_no.end` are specified
|
|
<6> Include the `lte` clause only if `line_no.end` is specified
|
|
<7> Fill in the value of param `line_no.end`
|
|
|
|
[NOTE]
|
|
==================================
|
|
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-templates>>) or, when used
|
|
via the REST API, should be written as a string:
|
|
|
|
[source,js]
|
|
--------------------
|
|
"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}}}}}}"
|
|
--------------------
|
|
|
|
==================================
|
|
|
|
[float]
|
|
[[pre-registered-templates]]
|
|
===== Pre-registered template
|
|
|
|
You 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:
|
|
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
GET /_search/template
|
|
{
|
|
"file": "storedTemplate", <1>
|
|
"params": {
|
|
"query_string": "search for these words"
|
|
}
|
|
}
|
|
------------------------------------------
|
|
|
|
<1> Name of the query template in `config/scripts/`, i.e., `storedTemplate.mustache`.
|
|
|
|
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.
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
POST /_search/template/<templatename>
|
|
{
|
|
"template": {
|
|
"query": {
|
|
"match": {
|
|
"title": "{{query_string}}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
------------------------------------------
|
|
|
|
This template can be retrieved by
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
GET /_search/template/<templatename>
|
|
------------------------------------------
|
|
|
|
which is rendered as:
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
{
|
|
"template": {
|
|
"query": {
|
|
"match": {
|
|
"title": "{{query_string}}"
|
|
}
|
|
}
|
|
}
|
|
}
|
|
------------------------------------------
|
|
|
|
This template can be deleted by
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
DELETE /_search/template/<templatename>
|
|
------------------------------------------
|
|
|
|
To use an indexed template at search time use:
|
|
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
GET /_search/template
|
|
{
|
|
"id": "templateName", <1>
|
|
"params": {
|
|
"query_string": "search for these words"
|
|
}
|
|
}
|
|
------------------------------------------
|
|
<1> Name of the query template stored in the `.scripts` index.
|
|
|
|
[float]
|
|
==== Validating templates
|
|
|
|
A template can be rendered in a response with given parameters using
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
GET /_render/template
|
|
{
|
|
"inline": {
|
|
"query": {
|
|
"terms": {
|
|
"status": [
|
|
"{{#status}}",
|
|
"{{.}}",
|
|
"{{/status}}"
|
|
]
|
|
}
|
|
}
|
|
},
|
|
"params": {
|
|
"status": [ "pending", "published" ]
|
|
}
|
|
}
|
|
------------------------------------------
|
|
|
|
This call will return the rendered template:
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
{
|
|
"template_output": {
|
|
"query": {
|
|
"terms": {
|
|
"status": [ <1>
|
|
"pending",
|
|
"published"
|
|
]
|
|
}
|
|
}
|
|
}
|
|
}
|
|
------------------------------------------
|
|
<1> `status` array has been populated with values from the `params` object.
|
|
|
|
File and indexed templates can also be rendered by replacing `inline` with
|
|
`file` or `id` respectively. For example, to render a file template
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
GET /_render/template
|
|
{
|
|
"file": "my_template",
|
|
"params": {
|
|
"status": [ "pending", "published" ]
|
|
}
|
|
}
|
|
------------------------------------------
|
|
|
|
Pre-registered templates can also be rendered using
|
|
|
|
[source,js]
|
|
------------------------------------------
|
|
GET /_render/template/<template_name>
|
|
{
|
|
"params": {
|
|
"..."
|
|
}
|
|
}
|
|
------------------------------------------
|