通过 ElasticSearch 6 中的子聚合进行过滤、排序和分页
Filtering, sorting and paginating by sub-aggregations in ElasticSearch 6
我有一个文件集,其中每个文件都表示给定酒店和日期的可用房间,以及当天的费用:
{
"hotel_id": 2016021519381313,
"day": "20200530",
"rooms": [
{
"room_id": "00d70230ca0142a6874358919336e53f",
"rate": 87
},
{
"room_id": "675a5ec187274a45ae7a5fdc20f72201",
"rate": 53
}
]
}
作为映射:
{
"properties": {
"day": {
"type": "keyword"
},
"hotel_id": {
"type": "long"
},
"rooms": {
"type": "nested",
"properties": {
"rate": {
"type": "long"
},
"room_id": {
"type": "keyword"
}
}
}
}
}
我想弄明白,如何进行查询,在其中我可以获得总费用低于给定金额的一组天数的可用房间,按总费用升序排列排序和分页。
到目前为止,我想出了在这组日子里获得可用房间的方法以及它们的总费用。基本上是按天过滤,按酒店和房间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" } }
}
}
}
}
}
}
}
}
所以现在我感兴趣的是根据 "rooms" 子聚合的值在 "hotel" 级别对结果桶进行降序排序,并过滤不符合条件的桶包含足够的文档或 "sum_price" 超出给定预算。但是我不知道怎么做。
我一直在查看 "bucket_sort",但我找不到在子聚合基础上进行排序的方法。我也一直在查看 "bucket_selector",但当它们不符合谓词时,它会给我空桶。在我的情况下,我可能没有正确使用它们。
哪种方法才是正确的实现方式?
这里是查询没有分页:
{
"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"
}
}
}
}
}
}
}
}
请注意,应更改以下变量以获得所需的结果:
- 天
- min_doc_count
- max_price
中的脚本
我有一个文件集,其中每个文件都表示给定酒店和日期的可用房间,以及当天的费用:
{
"hotel_id": 2016021519381313,
"day": "20200530",
"rooms": [
{
"room_id": "00d70230ca0142a6874358919336e53f",
"rate": 87
},
{
"room_id": "675a5ec187274a45ae7a5fdc20f72201",
"rate": 53
}
]
}
作为映射:
{
"properties": {
"day": {
"type": "keyword"
},
"hotel_id": {
"type": "long"
},
"rooms": {
"type": "nested",
"properties": {
"rate": {
"type": "long"
},
"room_id": {
"type": "keyword"
}
}
}
}
}
我想弄明白,如何进行查询,在其中我可以获得总费用低于给定金额的一组天数的可用房间,按总费用升序排列排序和分页。
到目前为止,我想出了在这组日子里获得可用房间的方法以及它们的总费用。基本上是按天过滤,按酒店和房间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" } }
}
}
}
}
}
}
}
}
所以现在我感兴趣的是根据 "rooms" 子聚合的值在 "hotel" 级别对结果桶进行降序排序,并过滤不符合条件的桶包含足够的文档或 "sum_price" 超出给定预算。但是我不知道怎么做。
我一直在查看 "bucket_sort",但我找不到在子聚合基础上进行排序的方法。我也一直在查看 "bucket_selector",但当它们不符合谓词时,它会给我空桶。在我的情况下,我可能没有正确使用它们。
哪种方法才是正确的实现方式?
这里是查询没有分页:
{
"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"
}
}
}
}
}
}
}
}
请注意,应更改以下变量以获得所需的结果:
- 天
- min_doc_count
- max_price 中的脚本