123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371 |
- [[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": {
- "..."
- }
- }
- ------------------------------------------
|