Search Template
所谓 search template 搜索模板其实就是:
1.预先定义好查询语句 DSL 的结构并预留参数2.搜索的时再传入参数值3.渲染出完整的 DSL ,最后进行搜索
使用搜索模板可以将 DSL 从应用程序中解耦出来,并且可以更加灵活的更改查询语句。
例如:
GET _search/template { "source" : { "query": { "match" : { "{{my_field}}" : "{{my_value}}" } } }, "params" : { "my_field" : "message", "my_value" : "foo" } }
构造出来的 DSL 就是:
{ "query": { "match": { "message": "foo" } } }
在模板中通过 {{ }}
的方式预留参数,然后查询时再指定对应的参数值,最后填充成具体的查询语句进行搜索。
搜索模板 API
为了实现搜索模板和查询分离,我们首先需要单独保存和管理搜索模板。
保存搜索模板
使用 scripts API 保存搜索模板(不存在则创建,存在则覆盖)。示例:
POST _scripts/<templateid> { "script": { "lang": "mustache", "source": { "query": { "match": { "title": "{{query_string}}" } } } } }
查询搜索模板
GET _scripts/<templateid>
删除搜索模板
DELETE _scripts/<templateid>
使用搜索模板
示例:
GET _search/template { "id": "<templateid>", "params": { "query_string": "search words" } }
params
中的参数与搜索模板中定义的一致,上文保存搜索模板的示例是 {{query_string}}
,所以这里进行搜索时对应的参数就是 query_string
。
检验搜索模板
有时候我们想看看搜索模板输入了参数之后渲染成的 DSL 到底长啥样。
示例:
GET _render/template { "source": "{ \"query\": { \"terms\": {{#toJson}}statuses{{/toJson}} }}", "params": { "statuses" : { "status": [ "pending", "published" ] } } }
返回的结果就是:
{ "template_output": { "query": { "terms": { "status": [ "pending", "published" ] } } } }
{{#toJson}} {{/toJson}}
就是转换成 json 格式。/
已经保存的搜索模板可以通过以下方式查看渲染结果:
GET _render/template/<template_name> { "params": { "..." } }
使用 explain
和 profile
参数
示例:
GET _search/template { "id": "my_template", "params": { "status": [ "pending", "published" ] }, "explain": true }
GET _search/template { "id": "my_template", "params": { "status": [ "pending", "published" ] }, "profile": true }
模板渲染
填充简单值
GET _search/template { "source": { "query": { "term": { "message": "{{query_string}}" } } }, "params": { "query_string": "search words" } }
对应的 DSL 就是:
{ "query": { "term": { "message": "search words" } } }
将参数转换为 JSON
使用 {{#toJson}}parameter{{/toJson}}
会将参数转换为 JSON。
GET _search/template { "source": "{ \"query\": { \"terms\": {{#toJson}}statuses{{/toJson}} }}", "params": { "statuses" : { "status": [ "pending", "published" ] } } }
对应的 DSL 就是:
{ "query": { "terms": { "status": [ "pending", "published" ] } } }
对象数组的渲染示例:
GET _search/template { "source": "{\"query\":{\"bool\":{\"must\": {{#toJson}}clauses{{/toJson}} }}}", "params": { "clauses": [ { "term": { "user" : "foo" } }, { "term": { "user" : "bar" } } ] } }
渲染结果就是:
{ "query": { "bool": { "must": [ { "term": { "user" : "foo" } }, { "term": { "user" : "bar" } } ] } } }
将数组 join 成字符串
使用 {{#join}}array{{/join}}
可以将数组 join 成字符串。
示例:
GET _search/template { "source": { "query": { "match": { "emails": "{{#join}}emails{{/join}}" } } }, "params": { "emails": [ "aaa", "bbb" ] } }
渲染结果:
{ "query" : { "match" : { "emails" : "aaa,bbb" } } }
除了默认以 ,
分隔外,还可以自定义分隔符,示例:
{ "source": { "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" ] } } }
例子中的 {{#join delimiter='||'}} {{/join delimiter='||'}}
意思就是进行 join 操作,分隔符设置为 ||
,渲染结果就是:
{ "query": { "range": { "born": { "gte": "2016", "lte": "31/12/2017", "format": "dd/MM/yyyy||yyyy" } } } }