我想制作一个排行榜,以便显示每个用户在游戏结束时的排名。 这是数据字段:
{
"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做排行榜?
在任何情况下,要计算人员的准确排名,您需要首先计算每个人的分数,这是 Elastic 中没有的。所以我认为更好的方法是存储每个人的总分。
如果您想采用您的方法,您可以简单地增加聚合的大小并获取所有用户的分数并在您的应用程序中找到排名。如果您有很多用户,这显然行不通,因为 Elastic 的大小有限。为此,您可以查看composite agg。