Elasticsearch逆范围重叠查询

时间:2016-06-03 20:23:59

标签: elasticsearch

我有以下文件:

{
  "blocked_availabilities": [
    {
      "start_time": "2016-05-26T19:30:00Z",
      "end_time": "2016-05-26T20:30:00Z"
    },
    {
      "start_time": "2017-05-26T16:00:00Z",
      "end_time": "2017-05-26T17:00:00Z",
    }
  ]
}

blocked_availabilities是映射中的嵌套类型。

我要做的是匹配与指定的开始和结束时间重叠的文档。我有以下查询来执行此操作(当然,这不起作用):

{
  "query":{
    "bool":{
      "filter":{
        "nested":{
          "path":"blocked_availabilities",
          "query":{
            "bool":{
              "must_not":{
                "bool":{
                  "must":[
                    {
                      "range":{
                        "blocked_availabilities.start_time":{
                          "from":null,
                          "include_lower":true,
                          "include_upper":true,
                          "to":"2016-05-26T20:00:00Z"
                        }
                      }
                    },
                    {
                      "range":{
                        "blocked_availabilities.end_time":{
                          "from":"2016-05-26T19:00:00Z",
                          "include_lower":true,
                          "include_upper":true,
                          "to":null
                        }
                      }
                    }
                  ]
                }
              }
            }
          }
        }
      }
    }
  }
}

问题似乎是其中一个嵌套文档匹配,因此返回整个文档。

有没有一个好方法可以做我想要的?我希望我的查询不会返回此文档,因为它与第一个嵌套文档重叠。

2 个答案:

答案 0 :(得分:1)

实现此目的的一种方法是检查是否存在任何具有重叠周期的嵌套对象,并且必须执行嵌套查询。 这将最终匹配仅在期望的时间段内不包含任何blocked_availabilities重叠的文档。

示例:

设置索引

put test

put test/test/_mapping
{

      "properties": {
         "blocked_availabilities": {
            "type": "nested",
            "properties": {
               "start_time": {
                  "type": "date"
               },
               "end_time": {
                  "type": "date"
               }
            }
         }
      }
   }
}


put test/test/1
{
   "blocked_availabilities": [
      {
         "start_time": "2016-05-26T19:30:00Z",
         "end_time": "2016-05-26T20:30:00Z"
      },
      {
         "start_time": "2017-05-26T16:00:00Z",
         "end_time": "2017-05-26T17:00:00Z"
      }
   ]
}

查询:

put test/test/_search
{
   "query": {
      "bool": {
         "must_not": [
            {
               "nested": {
                  "path": "blocked_availabilities",
                  "query": {
                     "bool": {
                        "should": [
                           {
                              "range": {
                                 "blocked_availabilities.end_time": {
                                    "lte": "2016-05-26T20:00:00Z",
                                    "gte": "2016-05-26T19:00:00Z"
                                 }
                              }
                           },
                           {
                              "range": {
                                 "blocked_availabilities.start_time": {
                                    "lte": "2016-05-26T20:00:00Z",
                                    "gte": "2016-05-26T19:00:00Z"
                                 }
                              }
                           }
                        ]
                     }
                  }
               }
            }
         ]
      }
   }
}

答案 1 :(得分:0)

您正试图制作not ((start > s) and (end < e))。为什么不简单地制作(start > e) or (end < s)?如果数据一致,它看起来应该有效。