在Elasticsearch中按子聚合筛选父级

时间:2017-03-24 16:09:58

标签: search elasticsearch

我在ES映射中有一个父子关系,我希望通过子项上的聚合(avg)值来过滤父项。也就是说,我只想检索那个值在给定范围内的父母。

我尝试使用aggs和后置过滤器,但无法使其正常工作。

{
  "apartments" : {
    "mappings" : {
      "apartment_availability" : {
        "_parent" : {
          "type" : "apartment"
        },
        "_routing" : {
          "required" : true
        },
        "properties" : {
          "availability_date" : {
            "type" : "date"
          },
          "apartment_id" : {
            "type" : "long"
          },
          "id" : {
            "type" : "long"
          },
          "price_cents" : {
            "type" : "long"
          },
          "status" : {
            "type" : "text",
            "fields" : {
              "keyword" : {
                "type" : "keyword",
                "ignore_above" : 256
              }
            }
          }
        }
      },
      "apartment" : {
        "properties" : {
          "id" : {
            "type" : "long"
          },
        }
      }
    }
  }
}

如果oru用户选择3月24日 - 3月31日的期间以及150欧元至300欧元的价格范围,那么我们希望向他们展示该期间免费的所有公寓,其中该期间的平均价格是€150-€300范围。

这是我们到目前为止所拥有的:

{
  "query": {
    "bool": {
      "filter": {
        "bool": {
          "must": [{
            "has_child": {
              "type": "apartment_availability",
              "min_children": 8,
              "max_children": 8,
              "query": {
                "bool": {
                  "must": [{
                    "term": {
                      "status": "available"
                    }
                  }, {
                    "range": {
                      "availability_date": {
                        "gte": "2017-03-24",
                        "lte": "2017-03-31"
                      }
                    }
                  }]
                }
              }
            }
          }]
        }
      }
    }
  }
}

1 个答案:

答案 0 :(得分:0)

我的建议是,使用GET /apartments/apartment/_search { "query": { "bool": { "filter": { "bool": { "must": [ { "has_child": { "type": "apartment_availability", "query": { "bool": { "must": [ { "term": { "status": "available" } }, { "range": { "availability_date": { "gte": "2017-04-01", "lte": "2017-04-03" } } } ] } } } } ] } } } }, "aggs": { "apartments_ids": { "terms": { "field": "id", "size": 10 }, "aggs": { "avails": { "children": { "type": "apartment_availability" }, "aggs": { "filter_avails": { "filter": { "bool": { "must": [ { "term": { "status": "available" } }, { "range": { "availability_date": { "gte": "2017-04-01", "lte": "2017-04-03" } } } ] } }, "aggs": { "average": { "avg": { "field": "price_cents" } } } } } }, "avg_bucket_filter": { "bucket_selector": { "buckets_path": { "avg": "avails>filter_avails.average" }, "script": "params.avg > 150 && params.avg < 300" } } } } } } 汇总在公寓之间进行选择:

// Just an example to present second level date/time calculation
let time = NSDate()
let interval:Double = 5.0
let timeFiveSecondLater = time.addingTimeInterval(interval)