skip to Main Content

I am trying to find a document in a MongoDB instance with the largest value of a particular field.

Here is the current code I have to do that:

document = collection.find().sort('experiment_id', -1).limit(1)

if document is None:
    # ...
else:
    return document['experiment_id']

I am using this query format (find() followed by sort() combined with limit(1) because this is supposed to be interpreted by Mongo in a highly optimized way.

However, this does not work because document is a cursor type, therefore one cannot call ['experiment_id'] on it.

What I find slightly suprising is that limit(1) returns a cursor object and not a single value or None type.

How should I write a pymongo query which finds the largest value of the field 'experiment_id' from a collection of documents?

It seems obvious that the following will work but it doesn’t seem like a particularly good solution.

for document in documents:
    return document['experiment_id']

2

Answers


  1. Since you want only one result – as a document, rather than a cursor, you could use find_one() with a sort criteria which behaves like it does as a param to find(), and drop the limit clause, since it will be ignored anyway.

    find_one(filter=None, *args, **kwargs)

    Returns a single document, or None if no matching document is found.

    document = collection.find_one({}, sort={'experiment_id': -1})
    
    if document is None:
        # ...
    else:
        return document['experiment_id']
    

    Additionally, if you want just the ‘experiment_id’ and none of the rest, you can use a projection which would return a document with only the specified fields.

    document = collection.find_one(
        {},
        sort={'experiment_id': -1},
        projection={'_id': False, 'experiment_id': True}  # only experiment_id
    )
    
    if document:
        return document['experiment_id']
    # else logic here
    
    Login or Signup to reply.
  2. Your code

    collection.find().sort(‘experiment_id’, -1).limit(1)

    returns a cursor.

    collection‘s find always returns a cursor (irrespective of the number of documents the find returns). In case there is no result document the cursor will be empty with zero documents.

    You can perform many operations on a cursor, and one of them is to iterate the cursor. Using this,

    documents = collection.find().sort('experiment_id', -1).limit(1)
    document = None
    for doc in documents:
        document = doc
    if (document):
        print('Max experiment id', document['experiment_id'])
    else:
        print('No documents in the collection')
    

    References:

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search