Get document's placement in collection based on sort order Get document's placement in collection based on sort order mongoose mongoose

Get document's placement in collection based on sort order


If you don't have to get the placement in real time, Neil Lunn's answer is perfect. But if your app has always data to insert in this collection, for the new data, you can't get the placement for it.

Here is another solution:

Firstly, you add index on the field score in this collection. Then use query db.highscores.count({score:{$gt: user's score}). It will count the documents whose score it greater than the target. This number is the placement.


It is possible to do this with mapReduce, but it does require that you have an index on the sorted field, so first, if you already have not done:

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 vary that to the information you need to return other than simply the "ranking" position. But since that is basically putting everything into a large array that has already been sorted by score then it probably will not be the best performance for any reasonable size of data.

A better solution would be to maintain a separate "rankings" collection, which you can again update periodically with mapReduce, even though it does not do any reducing:

db.highscores.mapReduce(    function() {        ranking++;        emit( ranking, this );    },    function() {},    {        "sort": { "score": -1 },        "scope": { "ranking": 0 },        "out": {            "replace": "rankings"        }    })

Then you can query this collection in order to get your results:

db.rankings.find({ "value.user": "User12 })

So that would contain the ranking as "emitted" in the _id field of the "rankings" collection.