通过ElasticSearch 6中的子聚合进行过滤,排序和分页

Vla*_*lad 7 elasticsearch elasticsearch-aggregation

我收集了一些文件,其中每个文件都指出了给定酒店和一天的可用客房,以及当天的费用:

{
    "hotel_id": 2016021519381313,
    "day": "20200530",
    "rooms": [
        {
            "room_id": "00d70230ca0142a6874358919336e53f",
            "rate": 87
        },
        {
            "room_id": "675a5ec187274a45ae7a5fdc20f72201",
            "rate": 53
        }
    ]
}
Run Code Online (Sandbox Code Playgroud)

作为映射:

{
    "properties": {
        "day": {
            "type": "keyword"
        },
        "hotel_id": {
            "type": "long"
        },
        "rooms": {
            "type": "nested",
            "properties": {
                "rate": {
                    "type": "long"
                },
                "room_id": {
                    "type": "keyword"
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

我正在尝试找出一个查询,在该查询中我可以获取一组总费用小于给定金额的天的可用客房,并按总费用升序排序并分页。

到目前为止,我想出了一种方式来获取当天可用的房间及其总费用。基本上是按天过滤,然后按酒店和房间ID进行分组,要求聚合中的最小计数是我要查找的天数。

{
    "size" : 0,
    "query": {
        "bool": { 
            "must": [
                {
                    "terms" : {
                        "day" : ["20200423", "20200424", "20200425"]
                    }
                }
            ]
        } 
    } ,
    "aggs" : {
        "hotel" : {
            "terms" : { 
                "field" : "hotel_id"
            },
            "aggs" : {
                "rooms" : {
                    "nested" : {
                        "path" : "rooms"
                    },
                    "aggs" : {
                        "rooms" : {
                            "terms" : {
                                "field" : "rooms.room_id",
                                "min_doc_count" : 3
                            },
                            "aggs" : {
                                "sum_price" : { 
                                    "sum" : { "field" : "rooms.rate" } }
                            }
                        }

                    }
                }
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

因此,现在我很有趣,可以根据带有“房间”的子聚合的值在“酒店”级别按降序对结果存储桶进行排序,还可以对没有足够文档或“ sum_price”为大于给定的预算。但是我无法管理该怎么做。

我一直在研究“ bucket_sort”,但找不到基于子聚合排序的方法。我也一直在研究“ bucket_selector”,但是当它们不适合谓词时,它会给我空的桶。我可能没有正确使用它们。

哪种方法才是正确的方法?

chu*_*ull 2

这是没有分页的查询:

{
   "size":0,
   "query":{
      "bool":{
         "must":[
            {
               "terms":{
                  "day":[
                     "20200530",
                     "20200531",
                     "20200532"
                  ]
               }
            }
         ]
      }
   },
   "aggs":{
      "rooms":{
         "nested":{
            "path":"rooms"
         },
         "aggs":{
            "rooms":{
               "terms":{
                  "field":"rooms.room_id",
                  "min_doc_count":3,
                  "order":{
                     "sum_price":"asc"
                  }
               },
               "aggs":{
                  "sum_price":{
                     "sum":{
                        "field":"rooms.rate"
                     }
                  },
                  "max_price":{
                     "bucket_selector":{
                        "buckets_path":{
                           "var1":"sum_price"
                        },
                        "script":"params.var1 < 100"
                     }
                  }
               }
            }
         }
      }
   }
}
Run Code Online (Sandbox Code Playgroud)

请注意,应更改以下变量以获得所需的结果:

  • 最小文档数
  • max_price 中的脚本