我正在将游泳比赛的结果存储在elasticsearch中,以便能够以不同的方式分析和显示数据。每个结果都存储为单独的文档,以毫秒为单位。像这样:
{
"swimmer": "xyz123",
"stroke": "butterfly",
"distance": 25,
"time": 20250
}
但是,对于年轻的游泳者来说,当他们在五种不同的事件类型(不同的击球方式)中达到特定的时间时,就会获得一个奖项,我希望能够找到所有时间都低于指定时间的游泳者。五个事件(不同事件的时间不同)。
示例: 游泳者完成以下项目即获得中杯奖: -在47秒或更短时间内完成50m仰泳 -在31秒或更短时间内释放50m(爬行) -在51秒或更短时间内达到50m的蛙泳 -22秒以内25m蝴蝶 -1m40s或更短时间内达到100m混合泳。
我尝试对每个笔划的每个限制使用由bool /必须查询组成的bool /应该查询。对此,我在“游泳者”->“中风”中具有聚合(术语“聚合”),并且可以基于存储桶数来确定游泳者是否在5冲程中达到了水平。
但是,这将为所有达到任何限制的所有游泳者返回一个水桶,尽管还不是很多(至今)游泳者,但我发现这从长远来看是行不通的。
我是否想念某些东西(运气不好)?谁能推荐在单个查询中实现此目标的方法?
简化查询:
{
"query": {
"bool": {
"should": [
{ //* backstroke, 50m, <47000ms *// },
{ //* freestroke, 50m, <41000ms *// },
{ //* breaststroke, 50m, <51000ms *// },
{ //* butterfly, 25m, <22000ms *// },
{ //* medley, 100m, <100000ms *// }
]
}
},
"aggs": {
"by_swimmer": {
"terms": {
"field": "swimmer"
},
"aggs": {
"by_stroke": {
"terms": {
"field": "stroke"
}
}
}
}
}
}
答案 0 :(得分:0)
查询将返回与单个或多个should子句匹配的任何文档。 您正在创建一个存储桶,其中包含单个游泳者的所有文档,然后您将这些文档按笔划类型进行划分。由于您的初始查询结果包含与任何奖项匹配的所有文档,因此您最终将得到描述的结果。 有多种方法可以解决这个问题。
您需要对每个奖励进行单独的查询,在must子句中包含过滤器查询。这样可以确保仅选择与奖励过滤器匹配的文档。
您更改查询以选择所有文档,例如做一个match all。然后,您可以处理聚合中的逻辑。您对游泳者保持术语聚合,以在一个存储桶中获得与单个游泳者匹配的所有文档。然后,将filter aggregations嵌套在每个奖励的游泳者级别上,如果其中包含游泳者已完成奖励的任何文件。
示例2:
{
"query" : {
"match_all" : {}
},
"aggs": {
"by_swimmer": {
"terms": {
"field": "swimmer"
},
"aggs": {
"stroke_award": {
"filter": {
"bool": {
"must": [{ //* backstroke, 50m, <47000ms *// }]
}
}
},
"freestroke_award": {
"filter": {
"bool": {
"must": [ { //* freestroke, 50m, <41000ms *// }]
}
}
},
"breaststroke_award": {
"filter": {
"bool": {
"must": [ { //* breaststroke, 50m, <51000ms *// }]
}
}
},
"butterfly_award": {
"filter": {
"bool": {
"must": [ { //* butterfly, 25m, <22000ms *// }]
}
}
},
"medley_award": {
"filter": {
"bool": {
"must": [ { //* medley, 100m, <100000ms *// }]
}
}
}
}
}
}
}
当其中一个存储桶中有文件时,将为游泳者颁奖。