2012-04-03 36 views
2

我將如何創建一個查詢來獲得當前球員的排名和周圍球員的排名。舉例來說,如果我有一個排行榜的收集與名字,並指出孟戈與周圍球員排名排行榜

{name: 'John', pts: 123} 

如果約翰在第23位,我會想顯示在第22和第24位的用戶的名稱爲好。

我可以查詢點數大於123的排行榜物品的數量來得到約翰的排名,但是我怎樣纔能有效地獲得排名在當前玩家之上和之下的玩家?我可以根據索引位置單獨獲取項目嗎?

我想我可以做2個查詢,率先拿到號碼的用戶,然後跳過限制查詢的排名位置,但似乎效率低下,似乎沒有一個高效使用索引

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

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

最後一個查詢似乎使用其索引掃描了24條記錄,有沒有一種方法可以合理地做到這一點與範圍查詢或更有效的?如果用戶排名很低,比如第50,000個,我可以看到這成爲一個問題。

回答

2

你需要做三個查詢:

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] 

創建的名稱和分指標。

+0

謝謝,你如何確保它是相鄰的記錄,而不是任何大於或小於的記錄..因爲我沒有看到它。另外,我試着用explain()來查看執行的查詢,並且它似乎沒有與findOne一起工作。我如何看待它使用的索引。 – MonkeyBonkey 2012-04-03 16:39:48

+0

colleciton.find({... query ...})。limit(-1).explain()等同於解釋findOne()。 – 2012-04-03 16:42:37

+0

所以在next_player查詢中,我如何確保它是下一個相鄰的排名,而不僅僅是比當前玩家更高的排名? – MonkeyBonkey 2012-04-04 23:59:42