This can be done using mapReduce , but this requires that you have an index in the sorted field, if you have not already done so:
db.highscores.ensureIndex({ "score": -1 })
Then you can do this:
db.highscores.mapReduce( function() { emit( null, this.user ); }, function(key,values) { return values.indexOf("User12") + 1; }, { "sort": { "score": -1 }, "out": { "inline": 1 } } )
Or change this to the information you need to return, and not just to the "ranking" position. But since it basically puts everything in a large array that has already been sorted by account, it probably won't be the best performance for any reasonable data size.
A better solution would be to maintain a separate “ranking” collection, which you can update again with mapReduce, even if it does not reduce:
db.highscores.mapReduce( function() { ranking++; emit( ranking, this ); }, function() {}, { "sort": { "score": -1 }, "scope": { "ranking": 0 }, "out": { "replace": "rankings" } } )
You can then query this collection to get your results:
db.rankings.find({ "value.user": "User12 })
So, this will contain the ranking as “emitted” in the _id field of the “ranking” collection.
source share