Elasticsearch中嵌套数组的范围过滤器

时间:2016-10-31 17:16:46

标签: elasticsearch

我可能不得不做一些内联groovy来做这件事,但它“感觉”就像我应该能够通过组合嵌套查询和范围查询来做到这一点,但事实上我使用的属性数组可能让这不可能。

假设我有一些产品的映射,我希望根据您在世界的哪个位置提供不同的交付估算,并且我已提前截止日期和时间并希望预加载一次一两个星期。

PUT /example_delivery
{
      "mappings": {
         "product": {
            "properties": {

               "delivery_times": {
                 "type": "nested",
                  "properties": {

                     "local_area": {
                        "type": "nested",
                        "properties": {
                           "cut_off_datetime": {
                              "type": "date", "format": "dateOptionalTime"
                           },
                           "get_it_by_date": {
                              "type": "date", "format": "dateOptionalTime"
                           }
                        }
                     },
                     "out_of_state": {
                       "type": "nested",
                        "properties": {
                           "cut_off_datetime": {
                              "type": "date", "format": "dateOptionalTime"
                           },
                           "get_it_by_date": {
                              "type": "date", "format": "dateOptionalTime"
                           }
                        }
                     }
                  }
               },
               "name": {
                  "type": "string"
               }
            }
         }
      }
   }

然后我决定加载一些产品:

PUT /example_delivery/product/1
{
  "name": "Product 1",
"delivery_times":[
  {"local_area":[
    {"cut_off_datetime": "2016-10-28T14:00:00", "get_it_by_date": "2016-10-29T13:00:00"},
    {"cut_off_datetime": "2016-10-31T14:00:00", "get_it_by_date": "2016-11-01T23:59:59"},
    {"cut_off_datetime": "2016-11-01T14:00:00", "get_it_by_date": "2016-11-02T23:59:59"},
    {"cut_off_datetime": "2016-11-02T14:00:00", "get_it_by_date": "2016-11-03T23:59:59"}
  ]},
  {"out_of_state":[
    {"cut_off_datetime": "2016-10-28T14:00:00", "get_it_by_date": "2016-11-01T23:59:59"},
    {"cut_off_datetime": "2016-10-31T14:00:00", "get_it_by_date": "2016-11-02T23:59:59"},
    {"cut_off_datetime": "2016-11-01T14:00:00", "get_it_by_date": "2016-11-03T23:59:59"},
    {"cut_off_datetime": "2016-11-02T14:00:00", "get_it_by_date": "2016-11-04T23:59:59"}
  ]}
]
}

PUT /example_delivery/product/2
{
  "name": "Product 2",
"delivery_times":[
  {"local_area":[
    {"cut_off_datetime": "2016-10-28T14:00:00", "get_it_by_date": "2016-11-29T13:00:00"},
    {"cut_off_datetime": "2016-10-31T14:00:00", "get_it_by_date": "2016-12-01T23:59:59"},
    {"cut_off_datetime": "2016-11-01T14:00:00", "get_it_by_date": "2016-12-02T23:59:59"},
    {"cut_off_datetime": "2016-11-02T14:00:00", "get_it_by_date": "2016-12-03T23:59:59"}
  ]},
  {"out_of_state":[
    {"cut_off_datetime": "2016-10-28T14:00:00", "get_it_by_date": "2016-12-01T23:59:59"},
    {"cut_off_datetime": "2016-10-31T14:00:00", "get_it_by_date": "2016-12-02T23:59:59"},
    {"cut_off_datetime": "2016-11-01T14:00:00", "get_it_by_date": "2016-12-03T23:59:59"},
    {"cut_off_datetime": "2016-11-02T14:00:00", "get_it_by_date": "2016-12-04T23:59:59"}
  ]}
]
}

我希望你能看到我的目标。我希望能够进行搜索,但在delivery_times.local_areadelivery_times.out_of_state的嵌套路径上应用过滤器,只返回至少有一个delivery_times对象的产品cut_off_datetime 1}}是gte"now",但get_it_by_datelte到用户在其过滤器中指定的目标时间。即使只是获得具有截止时间的匹配产品,也会导致空集:

GET example_delivery/_search
{
        "query" : { "match_all" : {} },
        "filter" : {
            "nested" : {
                "path" : "delivery_times",
                "filter" : {
        "range" : 
        {
        "delivery_times.local_area.cut_off_datetime" :           {
            "gte": "now"
          }
        } 
      } 
    }
  }
}

我想知道我是否需要更聪明地查询整个阵列,也许正如我所说的那样,使用内联groovy来做这件事,但我想知道是否有更简单的方法来做这个我只是现在没见。

1 个答案:

答案 0 :(得分:1)

你必须将一级降低到最终的嵌套级别。此查询将起作用。您还可以使用inner_hits来获取匹配的嵌套文档。

{
  "query": {
    "nested": {
      "path": "delivery_times",
      "query": {
        "bool": {
          "should": [
            {
              "nested": {
                "path": "delivery_times.out_of_state",
                "query": {
                  "range": {
                    "delivery_times.out_of_state.cut_off_datetime": {
                      "gte": "now"
                    }
                  }
                }
              }
            },
            {
              "nested": {
                "path": "delivery_times.local_area",
                "query": {
                  "range": {
                    "delivery_times.local_area.cut_off_datetime": {
                      "gte": "now"
                    }
                  }
                }
              }
            }
          ]
        }
      }
    }
  }
}