弹性胡子模板逻辑的控制部分

问题描述 投票:0回答:1

我有一个弹性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 的文档中可以看到的是,只有值可以是字符串(如上面的大小查询参数),而不是整个对象。

非常感谢您的指导。

elasticsearch mustache
1个回答
0
投票

我发现您的模板存在四个问题:

  1. {{#brand}}
    {{/brand}}
    标签出现在任何字符串之外,这是JSON语法不允许的。
  2. 无论
    query.bool.must
    是否存在,
    brand
    数组末尾都有一个尾随逗号。
  3. {{#codes}}
    {{/codes}}
    出现在单独的字符串中。或者,Elasticsearch 的模板机制不会识别这一点并崩溃(一旦您通过了无效的 JSON),或者它会默默地在
    query.bool.must[0].terms.code
    数组的开头和结尾插入空字符串,这可能不是您想要的也想要。
  4. 您缺少
    script.source
    的右大括号。

您链接到的 Elasticsearch 文档页面包含一些答案:

  • 您可以用逗号连接值将值呈现为JSON,这两种方法都可以避免在原始值数组中出现尾随逗号。
  • 关于 toJson
     的相同 
    部分提到
    source
    可以是字符串,在这种情况下,它将首先呈现为 Mustache 模板,并且生成的文本将被解析为 JSON。
  • 节上的部分显示了三引号语法,我认为这不是有效的 JSON,但 Elasticsearch 似乎仍然接受它。如果您使用字符串作为
    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    }"}]}
© www.soinside.com 2019 - 2024. All rights reserved.