Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.3k views
in Technique[技术] by (71.8m points)

mongodb - rank leaderboard in mongo with surrounding players

how would I create a query to get both the current player's rank and the surrounding player ranks. For example, if I had a leaderboard collection with name and points

{name: 'John', pts: 123}

If John was in 23rd place, I would want to show the names of users in the 22nd and 24th place as well.

I could query for a count of leader board items with pts greater than 123 to get John's rank, but how can I efficiently get the one player that is ranked just above and below the current player? Can I get items based on index position alone?

I suppose I can make 2 queries, first to get the number the rank position of a user, then a skip limit query, but that seems inefficient and doesn't seem to have an efficient use of the index

db.leaderboards.find({pts:{$gt:123}}).count();
-> 23

db.leaderboards.find().skip(21).limit(3)

The last query seems to scan across 24 records using the its index, is there a way I can reasonably do this with a range query or something more efficient? I can see this becoming an issue if the user is very low ranked, like 50,000th place.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You'll need to do three queries:

var john = db.players.findOne({name: 'John'})
var next_player = db.players.find(
    {_id: {$ne: john._id}, pts: {$gte: john.pts}}).sort({pts:1,name:1}).limit(-1)[0]
var previous_player = db.players.find(
    {_id: {$ne: john._id}, pts: {$lte: john.pts}}).sort({pts:-1,name:-1}).limit(-1)[0]

Create indexes on name and pts.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...