search-template.asciidoc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371
  1. [[search-template]]
  2. == Search Template
  3. The `/_search/template` endpoint allows to use the mustache language to pre render search requests,
  4. before they are executed and fill existing templates with template parameters.
  5. [source,js]
  6. ------------------------------------------
  7. GET /_search/template
  8. {
  9. "inline" : {
  10. "query": { "match" : { "{{my_field}}" : "{{my_value}}" } },
  11. "size" : "{{my_size}}"
  12. },
  13. "params" : {
  14. "my_field" : "foo",
  15. "my_value" : "bar",
  16. "my_size" : 5
  17. }
  18. }
  19. ------------------------------------------
  20. For more information on how Mustache templating and what kind of templating you
  21. can do with it check out the http://mustache.github.io/mustache.5.html[online
  22. documentation of the mustache project].
  23. NOTE: The mustache language is implemented in elasticsearch as a sandboxed
  24. scripting language, hence it obeys settings that may be used to enable or
  25. disable scripts per language, source and operation as described in
  26. <<enable-dynamic-scripting, scripting docs>>
  27. [float]
  28. ==== More template examples
  29. [float]
  30. ===== Filling in a query string with a single value
  31. [source,js]
  32. ------------------------------------------
  33. GET /_search/template
  34. {
  35. "inline": {
  36. "query": {
  37. "match": {
  38. "title": "{{query_string}}"
  39. }
  40. }
  41. },
  42. "params": {
  43. "query_string": "search for these words"
  44. }
  45. }
  46. ------------------------------------------
  47. [float]
  48. ===== Passing an array of strings
  49. [source,js]
  50. ------------------------------------------
  51. GET /_search/template
  52. {
  53. "inline": {
  54. "query": {
  55. "terms": {
  56. "status": [
  57. "{{#status}}",
  58. "{{.}}",
  59. "{{/status}}"
  60. ]
  61. }
  62. }
  63. },
  64. "params": {
  65. "status": [ "pending", "published" ]
  66. }
  67. }
  68. ------------------------------------------
  69. which is rendered as:
  70. [source,js]
  71. ------------------------------------------
  72. {
  73. "query": {
  74. "terms": {
  75. "status": [ "pending", "published" ]
  76. }
  77. }
  78. ------------------------------------------
  79. [float]
  80. ===== Default values
  81. A default value is written as `{{var}}{{^var}}default{{/var}}` for instance:
  82. [source,js]
  83. ------------------------------------------
  84. {
  85. "inline": {
  86. "query": {
  87. "range": {
  88. "line_no": {
  89. "gte": "{{start}}",
  90. "lte": "{{end}}{{^end}}20{{/end}}"
  91. }
  92. }
  93. }
  94. },
  95. "params": { ... }
  96. }
  97. ------------------------------------------
  98. When `params` is `{ "start": 10, "end": 15 }` this query would be rendered as:
  99. [source,js]
  100. ------------------------------------------
  101. {
  102. "range": {
  103. "line_no": {
  104. "gte": "10",
  105. "lte": "15"
  106. }
  107. }
  108. }
  109. ------------------------------------------
  110. But when `params` is `{ "start": 10 }` this query would use the default value
  111. for `end`:
  112. [source,js]
  113. ------------------------------------------
  114. {
  115. "range": {
  116. "line_no": {
  117. "gte": "10",
  118. "lte": "20"
  119. }
  120. }
  121. }
  122. ------------------------------------------
  123. [float]
  124. ===== Conditional clauses
  125. Conditional clauses cannot be expressed using the JSON form of the template.
  126. Instead, the template *must* be passed as a string. For instance, let's say
  127. we wanted to run a `match` query on the `line` field, and optionally wanted
  128. to filter by line numbers, where `start` and `end` are optional.
  129. The `params` would look like:
  130. [source,js]
  131. ------------------------------------------
  132. {
  133. "params": {
  134. "text": "words to search for",
  135. "line_no": { <1>
  136. "start": 10, <1>
  137. "end": 20 <1>
  138. }
  139. }
  140. }
  141. ------------------------------------------
  142. <1> All three of these elements are optional.
  143. We could write the query as:
  144. [source,js]
  145. ------------------------------------------
  146. {
  147. "query": {
  148. "bool": {
  149. "must": {
  150. "match": {
  151. "line": "{{text}}" <1>
  152. }
  153. },
  154. "filter": {
  155. {{#line_no}} <2>
  156. "range": {
  157. "line_no": {
  158. {{#start}} <3>
  159. "gte": "{{start}}" <4>
  160. {{#end}},{{/end}} <5>
  161. {{/start}} <3>
  162. {{#end}} <6>
  163. "lte": "{{end}}" <7>
  164. {{/end}} <6>
  165. }
  166. }
  167. {{/line_no}} <2>
  168. }
  169. }
  170. }
  171. }
  172. ------------------------------------------
  173. <1> Fill in the value of param `text`
  174. <2> Include the `range` filter only if `line_no` is specified
  175. <3> Include the `gte` clause only if `line_no.start` is specified
  176. <4> Fill in the value of param `line_no.start`
  177. <5> Add a comma after the `gte` clause only if `line_no.start`
  178. AND `line_no.end` are specified
  179. <6> Include the `lte` clause only if `line_no.end` is specified
  180. <7> Fill in the value of param `line_no.end`
  181. [NOTE]
  182. ==================================
  183. As written above, this template is not valid JSON because it includes the
  184. _section_ markers like `{{#line_no}}`. For this reason, the template should
  185. either be stored in a file (see <<pre-registered-templates>>) or, when used
  186. via the REST API, should be written as a string:
  187. [source,js]
  188. --------------------
  189. "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}}}}}}"
  190. --------------------
  191. ==================================
  192. [float]
  193. [[pre-registered-templates]]
  194. ===== Pre-registered template
  195. You can register search templates by storing it in the `config/scripts` directory, in a file using the `.mustache` extension.
  196. In order to execute the stored template, reference it by it's name under the `template` key:
  197. [source,js]
  198. ------------------------------------------
  199. GET /_search/template
  200. {
  201. "file": "storedTemplate", <1>
  202. "params": {
  203. "query_string": "search for these words"
  204. }
  205. }
  206. ------------------------------------------
  207. <1> Name of the query template in `config/scripts/`, i.e., `storedTemplate.mustache`.
  208. You can also register search templates by storing it in the elasticsearch cluster in a special index named `.scripts`.
  209. There are REST APIs to manage these indexed templates.
  210. [source,js]
  211. ------------------------------------------
  212. POST /_search/template/<templatename>
  213. {
  214. "template": {
  215. "query": {
  216. "match": {
  217. "title": "{{query_string}}"
  218. }
  219. }
  220. }
  221. }
  222. ------------------------------------------
  223. This template can be retrieved by
  224. [source,js]
  225. ------------------------------------------
  226. GET /_search/template/<templatename>
  227. ------------------------------------------
  228. which is rendered as:
  229. [source,js]
  230. ------------------------------------------
  231. {
  232. "template": {
  233. "query": {
  234. "match": {
  235. "title": "{{query_string}}"
  236. }
  237. }
  238. }
  239. }
  240. ------------------------------------------
  241. This template can be deleted by
  242. [source,js]
  243. ------------------------------------------
  244. DELETE /_search/template/<templatename>
  245. ------------------------------------------
  246. To use an indexed template at search time use:
  247. [source,js]
  248. ------------------------------------------
  249. GET /_search/template
  250. {
  251. "id": "templateName", <1>
  252. "params": {
  253. "query_string": "search for these words"
  254. }
  255. }
  256. ------------------------------------------
  257. <1> Name of the query template stored in the `.scripts` index.
  258. [float]
  259. ==== Validating templates
  260. A template can be rendered in a response with given parameters using
  261. [source,js]
  262. ------------------------------------------
  263. GET /_render/template
  264. {
  265. "inline": {
  266. "query": {
  267. "terms": {
  268. "status": [
  269. "{{#status}}",
  270. "{{.}}",
  271. "{{/status}}"
  272. ]
  273. }
  274. }
  275. },
  276. "params": {
  277. "status": [ "pending", "published" ]
  278. }
  279. }
  280. ------------------------------------------
  281. This call will return the rendered template:
  282. [source,js]
  283. ------------------------------------------
  284. {
  285. "template_output": {
  286. "query": {
  287. "terms": {
  288. "status": [ <1>
  289. "pending",
  290. "published"
  291. ]
  292. }
  293. }
  294. }
  295. }
  296. ------------------------------------------
  297. <1> `status` array has been populated with values from the `params` object.
  298. File and indexed templates can also be rendered by replacing `inline` with
  299. `file` or `id` respectively. For example, to render a file template
  300. [source,js]
  301. ------------------------------------------
  302. GET /_render/template
  303. {
  304. "file": "my_template",
  305. "params": {
  306. "status": [ "pending", "published" ]
  307. }
  308. }
  309. ------------------------------------------
  310. Pre-registered templates can also be rendered using
  311. [source,js]
  312. ------------------------------------------
  313. GET /_render/template/<template_name>
  314. {
  315. "params": {
  316. "..."
  317. }
  318. }
  319. ------------------------------------------