在带有Should子句的Elasticsearch中使用SearchTemplate进行日期范围查询

时间:2019-02-25 15:51:55

标签: elasticsearch date-range elasticsearch-template

我们有一个场景,我们必须使用“ OR”条件进行范围查询。 使用一个查询,它工作正常,但是在使用多个查询触发时出错。

POST _scripts/dateTemplate
{
  "script": {
    "lang": "mustache",
    "source": """
        {
        "query": {
            "bool": {
                "must": {
                "query_string": {
                    "query": "title:({{searchkeyword}})"
                }
            },
            "filter": {
                "bool":{
                    "must":[
                        {
                            "match_all": {}
                        }
                        {{#f_url}} , {
                            "terms" : {
                                "f_url": [{{#toJson}}f_url{{/toJson}} ]
                                }
                            }
                        {{/f_url}}
                    ],
                    "should":[
                        {{#since}}
                            {
                                "range": {
                                    "{{since}}": {
                                        {{#from}}"from": "{{from}}"{{#to}},{{/to}}{{/from}}
                                        {{#to}}"to":"{{to}}"{{/to}}
                                    }
                                }
                            }
                        {{/since}}
                    ]
                }
            }
        }
    }
    }
"""
  }
}

调用模板时查询

POST _search/template
{
  "id": "dateTemplate",
  "params": {
    "searchkeyword": "*",
    "since":[ {
      "since":"@timestamp",
      "from": "2018-06-01"
    },
     {
      "since":"@timestamp",
      "from": "2018-06-08"
    }
    ]
  }
}

错误

{
  "error": {
    "root_cause": [
      {
        "type": "json_parse_exception",
        "reason": "Unexpected character ('{' (code 123)): was expecting comma to separate Array entries\n at [Source: \t\t{\n\t\t\"query\": {\n\t\t\t\"bool\": {\n\t\t\t\t\"must\": {\n\t\t\t\t\"query_string\": {\n\t\t\t\t\t\"query\": \"title:(*)\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"filter\": {\n\t\t\t\t\"bool\":{\n\t\t\t\t\t\"must\":[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"match_all\": {}\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"should\":[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"range\": {\n\t\t\t\t\t\t\t\t\t\"@timestamp\": {\n\t\t\t\t\t\t\t\t\t\t\"from\": \"2018-06-01\"\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"range\": {\n\t\t\t\t\t\t\t\t\t\"@timestamp\": {\n\t\t\t\t\t\t\t\t\t\t\"from\": \"2018-06-08\"\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t}; line: 25, column: 9]"
      }
    ],
    "type": "json_parse_exception",
    "reason": "Unexpected character ('{' (code 123)): was expecting comma to separate Array entries\n at [Source: \t\t{\n\t\t\"query\": {\n\t\t\t\"bool\": {\n\t\t\t\t\"must\": {\n\t\t\t\t\"query_string\": {\n\t\t\t\t\t\"query\": \"title:(*)\"\n\t\t\t\t}\n\t\t\t},\n\t\t\t\"filter\": {\n\t\t\t\t\"bool\":{\n\t\t\t\t\t\"must\":[\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\"match_all\": {}\n\t\t\t\t\t\t}\n\t\t\t\t\t],\n\t\t\t\t\t\"should\":[\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"range\": {\n\t\t\t\t\t\t\t\t\t\"@timestamp\": {\n\t\t\t\t\t\t\t\t\t\t\"from\": \"2018-06-01\"\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\"range\": {\n\t\t\t\t\t\t\t\t\t\"@timestamp\": {\n\t\t\t\t\t\t\t\t\t\t\"from\": \"2018-06-08\"\n\t\t\t\t\t\t\t\t\t\t\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t}\n\t\t\t\t\t]\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n\t}; line: 25, column: 9]"
  },
  "status": 500
}

就像我在must子句中添加它一样,它在“ AND”条件下也可以正常工作。 您能否以“ AND”和“ OR”条件帮助构架模板?

1 个答案:

答案 0 :(得分:2)

您快到了,您只需要让胡子知道何时到达数组的最后一个元素即可。因此,您的模板应如下所示(即,我们在每个元素之后添加逗号(最后一个元素除外)):

  ...
                "should":[
                    {{#since}}
                        {
                            "range": {
                                "{{since}}": {
                                    {{#from}}"from": "{{from}}"{{#to}},{{/to}}{{/from}}
                                    {{#to}}"to":"{{to}}"{{/to}}
                                }
                            }
                        }{{^last}},{{/last}}                <-- modify this line
                    {{/since}}
                ]
  ...

然后只需修改您的调用,即可在last数组的最后一个元素中包含since标志:

POST _search/template
{
  "id": "dateTemplate",
  "params": {
    "searchkeyword": "*",
    "since":[ {
      "since":"@timestamp",
      "from": "2018-06-01"
    },
     {
      "since":"@timestamp",
      "from": "2018-06-08",
      "last": true                                         <-- add this line
    }
    ]
  }
}