我有一个弹性mustache模板,如下所示:
PUT /_scripts/get_content_thin
{
"script": {
"lang": "mustache",
"source": {
"_source": [
"type",
"code",
"name",
"brands"
],
"query": {
"bool": {
"must": [
{
"terms": {
"code": ["{{#codes}}","{{.}}","{{/codes}}"]
}
},
{
"term": {
"type": {
"value": "{{type}}"
}
}
},
{{#brand}}
{
"term": {
"brands": "{{brand}}"
}
},
{{/brand}}
]
}
},
"size": "{{size}}{{^size}}10{{/size}}"
}
}
这将通过以下方式调用:
POST /content/_search/template
{
"id": "get_content_thin",
"params": {
"codes": ["123456","654321"],
"size": 250,
"type": "football-club"
}
}
正如您在这里所看到的,我传递了
codes
、size
和 type
参数,但没有 brands
参数。
但是,模板不是有效的 JSON,因此无法将其插入到模板中。
有没有办法实现我正在寻找的位置,如果
brand
被发送(作为字符串),那么模板将评估 "term": { "brands": "{{brand}}" }
条件,如果没有发送,那么 Elastic 将不使用属性这个术语吗?
我对倒置部分的理解似乎是正确的,但我认为这与Elastic要求传入模板必须是有效的JSON相冲突。
我在 Elastic 的文档中可以看到的是,只有值可以是字符串(如上面的大小查询参数),而不是整个对象。
非常感谢您的指导。
我发现您的模板存在四个问题:
{{#brand}}
和{{/brand}}
标签出现在任何字符串之外,这是JSON语法不允许的。query.bool.must
是否存在,brand
数组末尾都有一个尾随逗号。{{#codes}}
和 {{/codes}}
出现在单独的字符串中。或者,Elasticsearch 的模板机制不会识别这一点并崩溃(一旦您通过了无效的 JSON),或者它会默默地在 query.bool.must[0].terms.code
数组的开头和结尾插入空字符串,这可能不是您想要的也想要。script.source
的右大括号。您链接到的 Elasticsearch 文档页面包含一些答案:
toJson
的相同 部分提到 source
可以是字符串,在这种情况下,它将首先呈现为 Mustache 模板,并且生成的文本将被解析为 JSON。source
属性,这可以节省大量转义。这些成分足以解决问题 1 和 3。对于问题 2,我们可以简单地删除末尾的逗号并在 brand
部分中使用
initial逗号代替。问题4是微不足道的。
将所有这些放在一起,应该可以工作:
PUT /_scripts/get_content_thin
{
"script": {
"lang": "mustache",
"source": """{
"_source": [
"type",
"code",
"name",
"brands"
],
"query": {
"bool": {
"must": [
{
"terms": {
"code": {{#toJson}}codes{{/toJson}}
}
},
{
"term": {
"type": {
"value": "{{type}}"
}
}
}{{#brand}},
{
"term": {
"brands": "{{brand}}"
}
}{{/brand}}
]
}
},
"size": "{{size}}{{^size}}10{{/size}}"
}"""
}
}
请记住,Elasticsearch 实现 lambda 的方式是非标准的。一般来说,lambda 不能以此处显示的方式访问上下文值,也不能以
join
文档 ({{#join delimiter='||'}}
) 中所示的方式接受参数。话虽这么说,我可以通过稍微修改输入数据来使 source
模板在 Mustache Playground 中工作。无论您是否从输入数据中删除 brand
,您都会看到没有尾随逗号。将此保存状态复制粘贴到其加载/存储框中:
{"data":{"text":" {\n \"codes\": [\"123456\",\"654321\"],\n \"size\": 250,\n \"type\": \"football-club\",\n \"brand\": 'x',\n toJson(param) {\n return JSON.stringify(this[param]);\n }\n }\n"},"templates":[{"name":"source","text":" {\n \"_source\": [\n \"type\",\n \"code\",\n \"name\",\n \"brands\"\n ],\n \"query\": {\n \"bool\": {\n \"must\": [\n {\n \"terms\": {\n \"code\": {{#toJson}}codes{{/toJson}}\n }\n },\n {\n \"term\": {\n \"type\": {\n \"value\": \"{{type}}\"\n }\n }\n }{{#brand}},\n {\n \"term\": {\n \"brands\": \"{{brand}}\"\n }\n }{{/brand}}\n ]\n }\n },\n \"size\": \"{{size}}{{^size}}10{{/size}}\"\n }"}]}