Home > Net >  Python MongoDB ranking index receiving?
Python MongoDB ranking index receiving?

Time:04-23

Hello!

I use the latest MongoDB (5.3) pymongo==4.1.1 I have a collection with users. Each of them has a 'points' key. When user opens his profile I want to shown his PLACE IN LEADERBOARD sorted by the 'points' key.

I've seen the $rank aggregation in the docs, but to make this query i should use the $setWindowFields, but I receive an error:

pymongo.errors.OperationFailure: Unrecognized pipeline stage name: '$setWindowFields', full error: {'ok': 0.0, 'errmsg': "Unrecognized pipeline stage name: '$setWindowFields'", 'code': 40324, 'codeName': 'Location40324'}

I've tried a lot of methods, but no one works. How to fix my problem, or advice me a new solution

[
    {"_id": 1, "points": 10},
    {"_id": 2, "points": 30},
    {"_id": 3, "points": 90},
    {"_id": 4, "points": 50}
]

For example I want to see the place if player with '_id': 3. I make some query and find out that his place is the 1st, because he has the greatest points value. I don't need to receive all the documents in collection, because there are even more than 100k documents. I need only index value.

There was a quite same question, but the goal hasn't reached there, using this method you receive sorted list of documents, and each of them just has its index, but anyway you can't find the index of one current document with the particular '_id' :(

Thank you for your help!

CodePudding user response:

Query1

  • this is simple example of how to do it, i think you need this
  • you can replace the 3 with the _id value

Playmongo

aggregate(
[{"$setWindowFields": 
   {"sortBy": {"points": -1}},"output": {"rank": {"$rank": {}}}},
 {"$match": {"$expr": {"$eq": ["$_id", 3]}}},
 {"$project": {"_id": 0, "rank": 1}}])

Query2

  • more complicated but its 1 query, and without $setWindowFields

Playmongo

coll.aggregate(
[{"$match": {"$expr": {"$eq": ["$_id", 2]}}},
 {"$lookup": 
   {"from": "coll",
    "pipeline": 
     [{"$match": {"$expr": {"$gte": ["$points", "$$points"]}}},
       {"$count": "count"}],
    "as": "rank",
    "let": {"points": "$points"}}},
 {"$project": {"_id": 0, "rank": {"$first": "$rank"}}}])

Query3

You can also send 2 simpler queries

  • find to get the points of the user
  • find and count to get the users with >= points (count in database not on client, or aggregate and count stage)

I don't know why it says unregognized stage, if you have >= MongoDB 5 it should be working.

  • Related