搜索模板
您可以将全文查询转换为搜索模板,以接受用户输入并将其动态插入到查询中。
例如,如果您使用 OpenSearch 作为您的应用程序或网站的后端搜索引擎,您可以从搜索栏或表单字段获取用户查询,并将其作为参数传递到搜索模板中。这样,创建 OpenSearch 查询的语法就对您的最终用户进行了抽象。
在编写将用户输入转换为 OpenSearch 查询的代码时,您可以使用搜索模板来简化代码。如果需要向搜索查询添加字段,只需修改模板即可,无需更改代码。
搜索模板使用 Mustache 语言。有关所有语法选项的列表,请参阅 Mustache 手册。
创建搜索模板
搜索模板有两个组成部分:查询和参数。参数是用户输入的值,它们被放入变量中。变量在 Mustache 符号中用双大括号表示。当在查询中遇到类似 {{var}}
的变量时,OpenSearch 会转到 params
部分,查找名为 var
的参数,并将其替换为指定的值。
您可以编写应用程序代码,询问用户他们想要搜索什么,然后在运行时将该值插入到 params
对象中。
此命令定义了一个搜索模板,用于按剧名查找剧本。查询中的 {{play_name}}
被值 Henry IV
替换。
GET _search/template
{
"source": {
"query": {
"match": {
"play_name": "{{play_name}}"
}
}
},
"params": {
"play_name": "Henry IV"
}
}
此模板在整个集群上运行搜索。要在特定索引上运行此搜索,请将索引名称添加到请求中。
GET shakespeare/_search/template
指定 from
和 size
参数
GET _search/template
{
"source": {
"from": "{{from}}",
"size": "{{size}}",
"query": {
"match": {
"play_name": "{{play_name}}"
}
}
},
"params": {
"play_name": "Henry IV",
"from": 10,
"size": 10
}
}
为了改善搜索体验,您可以定义默认值,这样用户就不必指定所有可能的参数。如果 params
部分未定义参数,OpenSearch 将使用默认值。
定义变量 var
默认值的语法如下:
{{var}}{{^var}}default value{{/var}}
此命令将 from
的默认值设置为 10,将 size
的默认值设置为 10。
GET _search/template
{
"source": {
"from": "{{from}}{{^from}}10{{/from}}",
"size": "{{size}}{{^size}}10{{/size}}",
"query": {
"match": {
"play_name": "{{play_name}}"
}
}
},
"params": {
"play_name": "Henry IV"
}
}
保存并执行搜索模板
在搜索模板按照您希望的方式工作后,您可以将该模板的源保存为脚本,使其可以重复用于不同的输入参数。
将搜索模板保存为脚本时,需要将 lang
参数指定为 mustache
。
POST _scripts/play_search_template
{
"script": {
"lang": "mustache",
"source": {
"from": "{{from}}{{^from}}0{{/from}}",
"size": "{{size}}{{^size}}10{{/size}}",
"query": {
"match": {
"play_name": "{{play_name}}"
}
}
},
"params": {
"play_name": "Henry IV"
}
}
}
现在,您可以通过引用其 id
参数来重用模板。您可以将此源模板重用于不同的输入值。
GET _search/template
{
"id": "play_search_template",
"params": {
"play_name": "Henry IV",
"from": 0,
"size": 1
}
}
示例响应
{
"took": 7,
"timed_out": false,
"_shards": {
"total": 6,
"successful": 6,
"skipped": 0,
"failed": 0
},
"hits": {
"total": {
"value": 3205,
"relation": "eq"
},
"max_score": 3.641852,
"hits": [
{
"_index": "shakespeare",
"_type": "_doc",
"_id": "4",
"_score": 3.641852,
"_source": {
"type": "line",
"line_id": 5,
"play_name": "Henry IV",
"speech_number": 1,
"line_number": "1.1.2",
"speaker": "KING HENRY IV",
"text_entry": "Find we a time for frighted peace to pant,"
}
}
]
}
}
如果您有存储的模板并希望验证它,请使用 render
操作。
POST _render/template
{
"id": "play_search_template",
"params": {
"play_name": "Henry IV"
}
}
有关更多信息,请参阅 渲染模板 API。
使用搜索模板进行高级参数转换
Mustache 中有许多不同的语法选项,可以将输入参数转换为查询。您可以指定条件、运行循环、连接数组、将数组转换为 JSON 等等。
条件
在 Mustache 中使用 section 标签表示条件
{{#var}}var{{/var}}
当 var
是一个布尔值时,此语法充当 if
条件。{{#var}}
和 {{/var}}
标签仅当 var
评估为 true
时才插入它们之间的值。
使用 section 标签会使您的 JSON 无效,因此您必须以字符串格式编写查询。
此命令仅在 limit
参数设置为 true
时才在查询中包含 size
参数。在以下示例中,limit
参数为 true
,因此 size
参数被激活。结果,您将只获得两个文档。
GET _search/template
{
"source": "{ {{#limit}} \"size\": \"{{size}}\", {{/limit}} \"query\":{\"match\":{\"play_name\": \"{{play_name}}\"}}}",
"params": {
"play_name": "Henry IV",
"limit": true,
"size": 2
}
}
您还可以设计一个 if-else
条件。如果 limit
为 true
,此命令将 size
设置为 2
。否则,它将 size
设置为 10
。
GET _search/template
{
"source": "{ {{#limit}} \"size\": \"2\", {{/limit}} {{^limit}} \"size\": \"10\", {{/limit}} \"query\":{\"match\":{\"play_name\": \"{{play_name}}\"}}}",
"params": {
"play_name": "Henry IV",
"limit": true
}
}
循环
您还可以使用 section 标签来实现 for-each 循环
{{#var}}{{.}}{{/var}}
当 var
是一个数组时,搜索模板会遍历它并创建一个 terms
查询。
GET _search/template
{
"source": "{\"query\":{\"terms\":{\"play_name\":[\"{{#play_name}}\",\"{{.}}\",\"{{/play_name}}\"]}}}",
"params": {
"play_name": [
"Henry IV",
"Othello"
]
}
}
此模板呈现为
GET _search/template
{
"source": {
"query": {
"terms": {
"play_name": [
"Henry IV",
"Othello"
]
}
}
}
}
连接
您可以使用 join
标签来连接数组的值(用逗号分隔)
GET _search/template
{
"source": {
"query": {
"match": {
"text_entry": "{{#join}}{{text_entry}}{{/join}}"
}
}
},
"params": {
"text_entry": [
"To be",
"or not to be"
]
}
}
呈现为
GET _search/template
{
"source": {
"query": {
"match": {
"text_entry": "{0=To be, 1=or not to be}"
}
}
}
}
转换为 JSON
您可以使用 toJson
标签将参数转换为其 JSON 表示形式
GET _search/template
{
"source": "{\"query\":{\"bool\":{\"must\":[{\"terms\": {\"text_entries\": {{#toJson}}text_entries{{/toJson}} }}] }}}",
"params": {
"text_entries": [
{ "term": { "text_entry" : "love" } },
{ "term": { "text_entry" : "soldier" } }
]
}
}
呈现为
GET _search/template
{
"source": {
"query": {
"bool": {
"must": [
{
"terms": {
"text_entries": [
{
"term": {
"text_entry": "love"
}
},
{
"term": {
"text_entry": "soldier"
}
}
]
}
}
]
}
}
}
}
多个搜索模板
您可以使用 msearch
操作将多个搜索模板捆绑在一起,并在单个请求中发送到 OpenSearch 集群。这可以节省网络往返时间,与独立请求相比,您可以更快地获得响应。
GET _msearch/template
{"index":"shakespeare"}
{"id":"if_search_template","params":{"play_name":"Henry IV","limit":false,"size":2}}
{"index":"shakespeare"}
{"id":"play_search_template","params":{"play_name":"Henry IV"}}
有关更多信息,请参阅 多搜索模板 API。
管理搜索模板
要列出所有脚本,请运行以下命令:
GET _cluster/state/metadata?pretty&filter_path=**.stored_scripts
要检索特定搜索模板,请运行以下命令:
GET _scripts/<name_of_search_template>
要删除搜索模板,请运行以下命令:
DELETE _scripts/<name_of_search_template>