简体   繁体   English

在Elasticsearch中按子聚合筛选父级

[英]Filter parent by children aggregation in Elasticsearch

I have a parent-children relationship in my ES mapping and I want to filter the parents by the value of an aggregation (avg) on their children. 我在ES映射中有一个父子关系,我希望通过子项上的聚合(avg)值来过滤父项。 That is, I only want to retrieve parents where that value is within a given range. 也就是说,我只想检索该值在给定范围内的父项。

I tried to do it with aggs and post-filters but couldn't get it to work. 我尝试使用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"
          },
        }
      }
    }
  }
}

If oru users select a period of March 24th-March 31st and a price range of €150-€300, then we want to show them all apartments that are free in that period and whose average price for that period is in the €150-€300 range. 如果oru用户选择3月24日至3月31日的期间和150至300欧元的价格范围,那么我们希望向他们展示在此期间免费的所有公寓,其平均价格为150欧元 - €300范围。

Here's what we have so far: 这是我们到目前为止所拥有的:

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

My suggestion, using bucket_selector aggregation to choose between apartments: 我的建议是,使用bucket_selector聚合在公寓之间进行选择:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM