ElasticSearch模板中Mustache循环报错:未正确闭合变量,求解决
Elasticsearch模板Mustache循环报错解决方法
问题场景
尝试在Elasticsearch搜索模板中使用Mustache语法循环动态生成filters聚合结构,运行时持续报错:
"reason" : "Improperly closed variable in query-template:1 @[query-template:1]"
即使补充完整索引映射、测试数据后,问题仍未解决。核心报错代码段为Mustache循环逻辑,调用请求及相关代码如下(完整示例见下文)。
错误原因
- 参数名含连字符解析歧义:Mustache在Elasticsearch中对带连字符(
-)的参数(如agg-att)解析存在问题,会导致模板解析器误判变量边界,引发未闭合变量错误。 - 手动处理逗号逻辑冗余且易出错:手动给最后一个元素添加
last: true来控制逗号的方式不仅繁琐,还容易在模板压缩时出现转义错误;实际上Elasticsearch的Mustache支持内置join辅助函数,无需手动处理。 - 模板压缩时的语法错误:手动压缩模板时,Mustache标签的嵌套和转义处理不当,导致解析器无法正确识别循环结构。
修复步骤
1. 修改参数命名
将含连字符的参数名(如agg-att)改为无特殊符号的格式,比如agg_att或aggAtt,避免解析歧义。
2. 使用Elasticsearch内置join辅助函数
利用{{#join}}自动处理数组元素间的逗号,无需手动判断last参数,简化逻辑同时避免错误。
3. 正确定义模板
优先使用多行字符串定义模板(避免手动压缩JSON的转义错误),或确保手动压缩时转义完全正确。
修正后的完整示例
索引映射(保持不变)
PUT tly-idx_test1 { "mappings": { "properties": { "fieldA": { "type": "keyword" }, "fieldArrayA": { "type": "keyword" }, "fieldArrayB": { "type": "nested", "properties": { "color": { "type": "keyword", "fields": { "text": { "type": "text", "analyzer": "standard" } } }, "size": { "type": "keyword", "fields": { "text": { "type": "text", "analyzer": "standard" } } }, "shape": { "type": "keyword", "fields": { "text": { "type": "text", "analyzer": "standard" } } }, "value": { "type": "keyword", "fields": { "text": { "type": "text", "analyzer": "standard" } } }, "obligatoire": { "type": "boolean" } } }, "fieldB": { "type": "text" }, "fieldC": { "type": "text" }, "fieldD": { "type": "text" }, "fieldE": { "type": "boolean" } } } }
测试数据(保持不变)
POST tly-idx_test1/_doc { "fieldA": "M", "fieldB": "SHOWER PACK", "fieldC": "false", "fieldD": "01", "fieldE": "true", "fieldArrayA": ["val1", "val2", "val3"], "fieldArrayB": [ {"color":"red","size":"10cm","shape":"square","obligatoire":true,"value":"15"}, {"color":"blue","size":"100cm","shape":"circle","obligatoire":true,"value":"25"}, {"color":"green","size":"50cm","shape":"rectangle","obligatoire":true,"value":"35"}, {"color":"yellow","size":"22cm","shape":"triangle","obligatoire":true,"value":"45"} ] }
修正后的模板定义
PUT _scripts/tly-template-test { "script": { "lang": "mustache", "source": """ { "query": { "match_all": {} }, "aggregations": { "agg-attributs": { "nested": { "path": "fieldArrayB" }, "aggs": { "att_obligatoire": { "filters": { "filters": { {{#join agg_att}} "{{code}}": {"term": {"fieldArrayB.{{code}}": "{{code}}"}} {{/join}} } }, "aggs": { "agg_by_value": { "terms": { "field": "fieldArrayB.value", "size": 10000 }, "aggs": { "top_reverse_nested": { "reverse_nested": {} } } } } } } } } } """ } }
模板调用请求
GET tly-idx_test1/_search/template { "id": "tly-template-test", "params": { "agg_att": [ {"code": "color"}, {"code": "shape"}, {"code": "size"} ] } }
关键说明
{{#join agg_att}}会自动遍历数组元素并在元素间添加逗号,无需手动处理last参数。- 参数名改为
agg_att后,彻底避免了连字符带来的解析歧义。 - 使用多行字符串(
"""包裹)定义模板,既保证结构清晰,又避免了手动压缩JSON时的转义错误。
内容的提问来源于stack exchange,提问作者toch
相关产品推荐
相关产品推荐

