Franz Payer
Franz Payer

Reputation: 4137

Mongodb get document position in collection

Is there a way to get a document's position relative to its collection based on one of its properties in Mongodb?

The use case is that I am building a leaderboard, but want to provide an easy way for the user to know their rank without having to scroll through all the entries.

Is there some mongoose schema magic or mongodb query that will help me easily get the position of a user based on their score?

Currently, my solution is to create an index on the score, query the entire collection and find the index of the user in the result.

Upvotes: 1

Views: 1687

Answers (2)

LoukilReda
LoukilReda

Reputation: 1

This is a 8 yo question but it would have helped if somebody had answered this question by giving a workaround at least over how to get the position of a document from MongoDB query.

Assuming I have a collection coll with the following documents :

[
  { "_id": "123e4567..", "username": "John", "gameScore": 85 },
  { "_id": "123e4567..", "username": "Alice", "gameScore": 95 },
  { "_id": "123e4567..", "username": "Bob", "gameScore": 75 },
  { "_id": "123e4567..", "username": "Eve", "gameScore": 90 }
]

I can get the score of a playerX by counting the number of players who have better gameScore than playerX + 1.

For the case described above, I am going to use MongoDB aggregation :

const player = { username: "John", gameScore: 85 };

const rankingQueryResult = coll.aggregate([
  {
    $sort: {
      gameScore: -1,
    },
  },
  {
    $match: {
      gameScore: { $gt: player.gameScore }, // get all player with score above 'John' score
    },
  },
  {
    $count: "passing_scores",
  },
  {
    $addFields: {
      rank: { $add: ["$passing_scores", 1] },
    },
  },
  {
    $project: {
      rank: 1,
    },
  },
]);

console.log(rankingQueryResult[0].rank) // 3

Upvotes: 0

André Peña
André Peña

Reputation: 173

Strictly speaking, this is not possible, as MongoDB does not store its documents in any certain order. Your current approach should be fine.

You're not the first one with this question: there's a feature request for this exact thing with a high priority.

https://jira.mongodb.org/browse/SERVER-4588

Upvotes: 2

Related Questions