OpenSearch/docs/reference/search/search-template.asciidoc

287 lines
6.5 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
{
"template" : {
"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].
[float]
==== More template examples
[float]
===== Filling in a query string with a single value
[source,js]
------------------------------------------
GET /_search/template
{
"template": {
"query": {
"match": {
"title": "{{query_string}}"
}
}
},
"params": {
"query_string": "search for these words"
}
}
------------------------------------------
[float]
===== Passing an array of strings
[source,js]
------------------------------------------
GET /_search/template
{
"template": {
"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]
------------------------------------------
{
"template": {
"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]
------------------------------------------
{
"filtered": {
"query": {
"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`
As written above, this template is not valid JSON because it includes the
_section_ markers like `{{#line_no}}`. For this reason, the template
can only be written as a string.
[float]
===== 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
{
"template": {
"file": "storedTemplate" <1>
},
"params": {
"query_string": "search for these words"
}
}
------------------------------------------
<1> Name of the 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
{
"template": {
"id": "templateName" <1>
},
"params": {
"query_string": "search for these words"
}
}
------------------------------------------
<1> Name of the the query template stored in the .scripts index.