gpt4 book ai didi

Elasticsearch - 根据分数对 userIds 进行排名

转载 作者:行者123 更新时间:2023-11-29 02:48:21 26 4
gpt4 key购买 nike

我正在尝试将我们旧 MySQL 数据库的一些查询迁移到我们新的 Elasticsearch 设置中。数据有点复杂,但归结为以下几点:

我有一个包含很多分数的索引。每个分数代表玩家在特定游戏中得分。

{
"userId": 2,
"scoreId": 3457,
"game": {
"id": 6,
"name": "scrabble"
},
"date": 1340047100,
"score": 56,
// and more game data
}

scoreId是这个分数的唯一id,game.id是那个游戏类型的id。

{
"userId": 6,
"gameId": 3479,
"game": {
"id": 5,
"name": "risk"
},
"date": "1380067200",
"score": 100,
// and more game data
}

多年来,人们玩了很多不同的游戏,我想对每种游戏的最佳玩家进行排名。排名是根据每位选手最好的6场比赛得出的。因此,例如,如果一个玩家玩了 10 次拼字游戏,则只有 6 个最好的分数计入总分。

我想创建一个列表:

// Scrabble ranking:
# | user | total points
1 | 2 | 4500
2 | 6 | 3200
2 | 23 | 1500

迁移的原因是旧的 MySQL 查询首先获取每个游戏的所有不同用户的列表,然后为每个用户执行另一个查询以获得其最好的 6 个分数。我希望我可以使用弹性聚合在一个查询中完成所有操作,但到目前为止我无法让它工作。

问题是,在阅读弹性文档几个小时后,我的问题似乎比示例更复杂。也许如果有人能指出我正确的方向,我可以继续我的搜索。至少这对我没有任何帮助:

GET /my-index/scores/_search
{
"query": {
"bool": {
"filter": [
{"term": { "game.id": 6 }}
]
}
},
"aggs": {
"scores": {
"terms": {
"field": "userId"
}
},
"top_scores_user": {
"top_hits": {
"sort": [{
"score": {
"order": "desc"
}
}],
"size" : 6
}
}
},
"size": 0
}

我使用的是 elastic 2.3,但如果确实有必要,我可以升级。

最佳答案

使用 top_hits 不会让您实现所需的目标,因为您无法对为热门命中聚合中的每个文档返回的字段执行操作。

解决此问题的一种方法是为用户使用顶级 terms 聚合(就像您所做的那样),然后为每个用户使用另一个 terms 子聚合您可以按降序排列的分数,只取 6 个最好的分数。最后,使用 pipeline sum_bucket aggregation ,您可以为每个用户总结这 6 个分数。

POST /my-index/scores/_search    
{
"size": 0,
"query": {
"bool": {
"filter": [
{
"term": {
"game.id": 6
}
}
]
}
},
"aggs": {
"users": {
"terms": { <--- segment by user
"field": "userId"
},
"aggs": {
"best_scores": {
"terms": { <--- 6 best scores for user
"field": "score",
"order": {
"_term": "desc"
},
"size": 6
},
"aggs": {
"total_score": {
"sum": {
"field": "score"
}
}
}
},
"total_points": { <--- total points for the user based on 6 best scores
"sum_bucket": {
"buckets_path": "best_scores > total_score"
}
}
}
}
}
}

请注意,此解决方案的一个缺点是,如果用户的分数完全相同,那么您将获得 7 个最佳分数而不是 6 个最佳分数,并且 total_score 值会太高.我们可以使用 avg 而不是 sum 度量聚合,但如果我们这样做,我们将忽略其中一个分数出现,这也不好。

另请注意,最好根据用户的 total_points 值对用户进行排序,但无法使用管道聚合进行排序(因为它们在 reduce 阶段之后运行)。排序需要在客户端进行。

关于Elasticsearch - 根据分数对 userIds 进行排名,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43764630/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com