我想做一个排名列表,以显示每个用户的排名时,一场比赛结束。这是数据字段:
{
"mappings": {
"properties": {
"userId":{
"type": "keyword"
},
"score":{
"type": "double"
},
"timeStamp":{
"type": "date"
}
}
}
}
每个用户都可以在游戏结束后得到一个分数,并在es中插入一个文档。我们可以通过以下方式获得用户在指定时间段内的总分数:
GET integral_stream/_search
{
"query": {
"bool": {
"filter": [
{
"term": {
"userId": "1"
},
"range": {
"timestamp": {
"gte": "2023-07-31T05:00:00.000Z",
"lte": "2023-08-07T04:59:59.999Z"
}
}
}
]
}
},
"size": 10,
"aggs": {
"users": {
"terms": {
"field": "userId"
},
"aggs": {
"total_score": {
"sum": {
"field": "score"
}
}
}
}
}
}
问题是:虽然我可以通过计算total_score的桶数来得到某个人的total_score排名,但是我怎么能通过一次搜索**来得到几个用户的排名呢?
如果我做不到这一点,我是否应该改变数据的结构,甚至给予使用es来制作排名列表?
1条答案
按热度按时间lb3vh1jj1#
在任何情况下,要计算人员的确切排名,您需要首先计算每个人的得分,这在Elastic中是没有的。所以我认为更好的方法是存储每个人的总分。
如果你想用你的方法,你可以简单地增加agg的大小,得到所有用户的分数,并在你的应用程序中找到排名。如果你有很多用户,这显然是行不通的,因为Elastic的大小是有限的。你可以看看composite agg。