我使用的是 Google App Engine,所以我使用的是非关系数据库 (NoSQL)。我的问题是:
使用他们的分数来建模排名(玩家排名)的最佳选择是什么?
例如,我的球员是:
Player { String name, int score}
我想知道一个球员的排名(位置),也想得到前 10 名球员,但我怀疑哪个是最好的方法。
谢谢。
我使用的是 Google App Engine,所以我使用的是非关系数据库 (NoSQL)。我的问题是:
使用他们的分数来建模排名(玩家排名)的最佳选择是什么?
例如,我的球员是:
Player { String name, int score}
我想知道一个球员的排名(位置),也想得到前 10 名球员,但我怀疑哪个是最好的方法。
谢谢。
如果您的分数已编入索引,则可以轻松进行数据存储查询并按排序顺序获取玩家。所以如果你想要前 10 名球员,那是非常微不足道的。
获得任意玩家的排名真的很难。我想说,如果可以,请避免使用它,如果不能,请找到绕过它的黑客方法。
例如,如果您有 50,000 名玩家,而 PlayerX 排名第 12,345 位,唯一知道的方法是查询所有玩家,并检查每个玩家,保持计数,直到找到 PlayerX。
一种技巧可能是将玩家排名存储在玩家实体中,并使用每隔几个小时运行一次的 cron 作业对其进行更新。
Redis有一个内置的解决方案:
首先添加几个有分数的成员:
redis> ZADD myzset 1 "one"
(integer) 1
redis> ZADD myzset 2 "two"
(integer) 1
redis> ZADD myzset 3 "three"
(integer) 1
获得“二”的等级:
redis> ZREVRANK myzset "one"
(integer) 2
(索引从 0 开始)
如果您想要当前订单:
redis> ZREVRANGE myzset 0 -1
1) "three"
2) "two"
3) "one"
您可以像这样设置 index.yaml:
- kind: Player
properties:
- name: score
direction: ascending
要获得玩家的分数,您只需对玩家进行传球(同时保持计数)并缓存结果以加快对该玩家的进一步搜索。
JSON 中的一个合适的表示是:
"players" : [
{
"name" : "John",
"score" : 15
},
{
"name" : "Swadq",
"score" : 7
},
{
"name" : "Jane",
"score" : 22
}
]
有关如何排序的示例: