/_search/template
端点允许使用mustache语言在执行前预渲染搜索请求,并使用模板参数填充现有模板。
GET /_search/template
{
"inline" : {
"query": { "match" : { "{{my_field}}" : "{{my_value}}" } },
"size" : "{{my_size}}"
},
"params" : {
"my_field" : "foo",
"my_value" : "bar",
"my_size" : 5
}
}
关于Mustache templating
以及你可以使用哪种模板,请参考 mustache
项目在线文档。
注意:
mustache
语言在elasticsearch中作为沙盒脚本语言实现,因此�对于启用或禁用,源代码和操作等设置,它遵从脚本文档的描述。
GET /_search/template
{
"inline": {
"query": {
"match": {
"title": "{{query_string}}"
}
}
},
"params": {
"query_string": "search for these words"
}
}
{{#toJson}}parameter{{/toJson}}
函数可以用来转换参数(比如maps
和array
)为它们的JSON
形式。
GET /_search/template
{
"inline": "{ \"query\": { \"terms\": { \"status\": {{#toJson}}status{{/toJson}} }}}",
"params": {
"status": [ "pending", "published" ]
}
}
其呈现为:
{
"query": {
"terms": {
"status": [
"pending",
"published"
]
}
}
}
更复杂的例子代替一个 JSON 对象数组:
{
"inline": "{\"query\":{\"bool\":{\"must\": {{#toJson}}clauses{{/toJson}} }}}",
"params": {
"clauses": [
{ "term": "foo" },
{ "term": "bar" }
]
}
}
呈现为:
{
"query" : {
"bool" : {
"must" : [
{
"term" : "foo"
},
{
"term" : "bar"
}
]
}
}
}
{{#join}}array{{/join}}
函数能用来将数组的值连接为以逗号分隔的字符串:
GET /_search/template
{
"inline": {
"query": {
"match": {
"emails": "{{#join}}emails{{/join}}"
}
}
},
"params": {
"emails": [ "[email protected]", "[email protected]" ]
}
}
其呈现为:
{
"query" : {
"match" : {
"emails" : "[email protected],[email protected]"
}
}
}
该函数还可以接受一个自定义分隔符:
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"]
}
}
}
呈现为:
{
"query" : {
"range" : {
"born" : {
"gte" : "2016",
"lte" : "31/12/2017",
"format" : "dd/MM/yyyy||yyyy"
}
}
}
}
默认值被写成{{var}}{{^var}}default{{/var}}
比如:
{
"inline": {
"query": {
"range": {
"line_no": {
"gte": "{{start}}",
"lte": "{{end}}{{^end}}20{{/end}}"
}
}
}
},
"params": { ... }
}
此时params
是 { "start": 10, "end": 15 }
,该查询可以呈现为:
{
"range": {
"line_no": {
"gte": "10",
"lte": "15"
}
}
}
但是, params
是{ "start": 10 }
时, 该查询就会使用默认值作为end
:
{
"range": {
"line_no": {
"gte": "10",
"lte": "20"
}
}
}
条件语句不能使用模板的 JSON 形式表示。相反,模板必须作为字符串传递。例如,假设我们想在line
字段上运行match
查询,并且可以选择用行号过滤其中start
和end
是可选的。
参数(params)会像这样:
{
"params": {
"text": "words to search for",
"line_no": { # ①
"start": 10, # ②
"end": 20 # ③
}
}
}
①、②、③ 所有这三个元素都是可选的。
查询语句我们可以是:
{
"query": {
"bool": {
"must": {
"match": {
"line": "{{text}}" # ①
}
},
"filter": {
{{#line_no}} # ②
"range": {
"line_no": {
{{#start}} # ③
"gte": "{{start}}" # ④
{{#end}},{{/end}} # ⑤
{{/start}} # ⑥
{{#end}} # ⑦
"lte": "{{end}}" # ⑧
{{/end}} # ⑨
}
}
{{/line_no}} # ⑩
}
}
}
}
① 填充text
参数值。
② 仅当指定line_no
时才能包含range
过滤器。
③ 仅当指定了line_no.start
时才能包含gte
子句。
④ 填充line_no.start
参数值。
⑤ 仅当line_no.start
和line_no.end
被指定时,在gte
子句后添加逗号。
⑦⑨ 仅当指定line_no.end
时,包含lte
子句。
⑩ 填充 line_no.end 参数值。
注意:
如上所述,模板不是有效的JSON 形式,因为它包含类似
{{line_no}}
的部分标记,因此,模板应存储在文件中(参考预注册模板一节)或者在通过REST API
使用时,应该将其写成字符串格式,比如:
{
"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}}}}}}"
}
可以使用{{#url}}value{{/ url}}
函数按HTML规范中定义的HTML编码格式对字符串值进行编码。
作为一个例子,编码一个URL是很有用的:
GET _render/template
{
"inline" : {
"query" : {
"term": {
"http_access_log": "{{#url}}{{host}}/{{page}}{{/url}}"
}
}
},
"params": {
"host": "https://www.elastic.co/",
"page": "learn"
}
}
前面的查询将呈现为:
{
"template_output" : {
"query" : {
"term" : {
"http_access_log" : "https%3A%2F%2Fwww.elastic.co%2F%2Flearn"
}
}
}
}
你可以通过将搜索模板存储在config/scripts
目录中,在使用 .mustache
扩展名的文件中注册搜索模板。为了执行存储的模板,请使用template
键下的名称来引用它:
GET /_search/template
{
"file": "storedTemplate", # ①
"params": {
"query_string": "search for these words"
}
}
① config/sripts/
查询模板的名称,即:storedTemplate.mustache
。
你还可以通过将搜索模板存储在集群状态中来注册搜索模板,由REST API
来管理这些索引的模板。
POST /_search/template/<templatename>
{
"template": {
"query": {
"match": {
"title": "{{query_string}}"
}
}
}
}
该模板可以通过以下方法来检查:
GET /_search/template/<templatename>
其可以呈现为:
{
"template": {
"query": {
"match": {
"title": "{{query_string}}"
}
}
}
}
这个模板可以被删除:
DELETE /_search/template/<templatename>
在搜索时使用索引模板,使用:
GET /_search/template
{
"id": "templateName", # ①
"params": {
"query_string": "search for these words"
}
}
① 存储在 .scripts 索引中的查询模板的名称。
可以在具有给定参数的响应中使用来呈现模板:
GET /_render/template
{
"inline": {
"query": {
"terms": {
"status": [
"{{#status}}",
"{{.}}",
"{{/status}}"
]
}
}
},
"params": {
"status": [ "pending", "published" ]
}
}
此次调用将返回呈现的模板:
{
"template_output": {
"query": {
"terms": {
"status": [ # ①
"pending",
"published"
]
}
}
}
}
① status 数据已使用来自 params 对象的值填充。
文件和索引模板也可以通过分别用file
或id
代替inline
来呈现。例如,呈现文件模板:
GET /_render/template
{
"file": "my_template",
"params": {
"status": [ "pending", "published" ]
}
}
预注册模板可以使用以下呈现:
GET /_render/template/<template_name>
{
"params": {
"..."
}
}
你可以在运行模板时使用Explain
参数:
GET _search/template
{
"file": "my_template",
"params": {
"status": [ "pending", "published" ]
},
"explain": true
}
你可以在运行模板时使用Profiling
参数:
GET _search/template
{
"file": "my_template",
"params": {
"status": [ "pending", "published" ]
},
"profile": true
}