如何控制Elastic Mustache模板逻辑并保证JSON有效性?
Elasticsearch Mustache模板条件添加bool查询子句的解决方案
需求与问题
要实现一个Mustache搜索模板:当传入brand参数时,在bool查询的must数组中添加针对brands字段的term查询;未传入则不包含该查询。但最初的模板因为不符合JSON规范无法导入Elasticsearch——直接在JSON结构中使用Mustache的区段语法会破坏JSON的有效性,而ES要求模板的source必须是合法的JSON结构。
原错误模板
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}}" } }
修正后的有效模板
PUT _scripts/get_content_thin { "script": { "lang": "mustache", "source": """{ "_source": [ "type", "code", "name", "brands" ], "query": { "bool": { "must": [ { "terms": { "code": {{#toJson}}codes{{/toJson}} } }, {{#brand}} { "term": { "brands": "{{brand}}" } }, {{/brand}} { "term": { "type": { "value": "{{type}}" } } } ] } }, "size": "{{size}}{{^size}}10{{/size}}" }""" } }
关键改动说明
- 将
source改为多行字符串:用三重引号(""")把模板内容包裹成字符串,这样Mustache的区段语法就不会破坏外层JSON的结构,Elasticsearch能正确解析模板。 - 使用
toJson内置方法处理数组参数:替换手动拼接的["{{#codes}}","{{.}}","{{/codes}}"]为{{#toJson}}codes{{/toJson}},ES会自动将参数数组序列化为合法的JSON数组,避免格式错误。 - 调整查询子句顺序:把可选的brand查询放在必填的type查询之前,这样当
brand参数不存在时,生成的JSON数组不会出现多余的逗号,保证最终查询的JSON有效性。
调用示例
POST /content/_search/template { "id": "get_content_thin", "params": { "codes": ["123456","654321"], "size": 250, "type": "football-club" } }
内容的提问来源于stack exchange,提问作者Dan Atkinson
相关产品推荐
相关产品推荐

