elasticsearch Elastic mustache模板逻辑的控制部分

h9a6wy2h  于 5个月前  发布在  ElasticSearch
关注(0)|答案(1)|浏览(59)

我有一个Elastic 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"
  }
}


正如您在这里看到的,我传入了codessizetype参数,但没有传入brands参数。
但是,模板不是有效的JSON,因此无法插入到模板中。
有没有一种方法可以实现我正在寻找的东西,如果brand被发送(作为字符串),那么模板将评估"term": { "brands": "{{brand}}" }条件,如果它没有被发送,那么Elastic将不会使用该terms属性?
我对倒排部分的理解似乎是正确的,但我认为这与Elastic的要求相冲突,即传入的模板必须是有效的JSON。
在Elastic的文档中,我所能看到的是只有值可以在字符串中(就像上面的size查询参数),而不是整个对象。
在此之前,我非常感谢你们的指导。

**编辑:**如接受的答案中所述,脚本模板中缺少一个结尾花括号(})。这是一个复制错误,我将为后代留下,以免接受的答案引起混乱。
**答案:**下面是我从Julian使用的accepted answer

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}}"
    }"""
  }
}

c7rzv4ha

c7rzv4ha1#

我看到你的模板有四个问题:

  1. {{#brand}}{{/brand}}标记出现在任何字符串之外,这是JSON语法所不允许的。
    1.在query.bool.must数组的末尾有一个逗号,不管brand是否存在。
  2. {{#codes}}{{/codes}}出现在不同的字符串中。要么,Elasticsearch的模板机制不会识别这一点并爆炸(一旦你让它通过无效的JSON),或者它会在query.bool.must[0].terms.code数组的开头和结尾悄悄插入空字符串,这可能也不是你想要的。
  3. script.source缺少一个右花括号。
    您链接到的Elasticsearch文档页面包含一些答案:
  • 您可以用逗号连接值或将值呈现为JSON,这两种方法都可以避免原始值数组中的尾随逗号。
  • 关于toJson的同一节提到source可以是字符串,在这种情况下,它将首先呈现为Mustache模板,生成的文本将被解析为JSON。
  • 关于section的部分显示了一个三重引号语法,我认为这不是有效的JSON,但Elasticsearch似乎无论如何都接受。如果您为source属性使用字符串,这可以保存大量转义。

这些成分足以解决问题1和3。对于问题2,我们可以简单地删除结尾的逗号,并在brand部分使用 * 开头 * 逗号。问题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实现Bundas的方式是非标准的。通常,Bundas不能以这里显示的方式访问上下文值,也不能以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    }"}]}

相关问题