💎一站式轻松地调用各大LLM模型接口,支持GPT4、智谱、星火、月之暗面及文生图 广告
# Search 模板 原文链接 : [https://www.elastic.co/guide/en/elasticsearch/reference/5.0/search-template.html](https://www.elastic.co/guide/en/elasticsearch/reference/5.0/search-template.html) 译文链接 : [http://www.apache.wiki/display/Elasticsearch](http://www.apache.wiki/display/Elasticsearch) 贡献者 : @Josh **/_search/template endpoint **允许我们在执行搜索请求和使用模板参数填充现有模板之前,能够使用 **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 项目在线文档](http://mustache.github.io/mustache.5.html)。 **NOTE:** 在 **elasticsearch** 中实现的 **mustache** 语言是作为一种沙箱(**sandboxed**) 脚本语言,因此它遵守相关设置,这些设置可能是为了启用或禁用 [脚本文档](http://apache.wiki/display/Elasticsearch/Scripting) 中描述的每个语言、源和操作。 ## 更多的模板案例 ### 使用单个值填充查询字符串 ``` GET /_search/template { "inline": { "query": { "match": { "title": "{{query_string}}" } } }, "params": { "query_string": "search for these words" } } ``` ### 将参数转换为 **JSON** **{{#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": [ "username@email.com", "lastname@email.com" ] } } ``` 其呈现为: ``` { "query" : { "match" : { "emails" : "username@email.com,lastname@email.com" } } } ``` 该函数还可以接受一个自定义分隔符: ``` 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** 形式,因为它包含类似 的部分标记,因此,模板应存储在文件中(参考 [预注册模板](http://apache.wiki/pages/viewpage.action?pageId=4882772) 一节)或者在通过 **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}}}}}}" ``` ### 预注册(Pre-registered)模板 你可以通过将搜索模板存储在 **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** 索引中的查询模板的名称。 ### 验证(Validating)模板 ``` 可以在具有给定参数的响应中使用来呈现模板: ``` ``` 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": { "..." } } ```