Navigation

MongoDB offers a lot of flexibility when querying for documents in the
database. Simon tries to expose that flexibility in easy to use ways.

To use one of MongoDB’s operators, append it to the name of the field
you want to apply it to, separated by a double underscore (__).
Simon will automatically translate it into the correct query syntax.

# match users where name is not equal to 'Simon'users=User.find(name__ne='Simon')# match users where score is greater than 1000users=User.find(score__gt=1000)# match users created in 2012fromdatetimeimportdatetimejan_1_2012=datetime(2012,1,1)jan_1_2013=datetime(2013,1,1)users=User.find(created__gte=jan_1_2012,created__lt=jan_1_2013)

One of the most powerful ways to query with MongoDB is through
geospatial querying. Unlike the operators discussed thus far, Simon
exposes the geospatial operators through convenience methods that help
harness the full potential of each operator.

Sometimes more complex queries require combining conditions with logical
operators, such as AND, OR, and NOT.

not

Performs a logical NOT operation on the specified expression.

users=User.find(score__not__gt=1000)

To perform this query in the mongo Shell:

users=db.users.find({score:{$not:{$gt:1000}}})

Using the AND and OR operators with Simon requires the
assistance of Q objects. Fortunately they work
just like any other query with Simon. Instead of passing the the query
directly to a method like find(), however, the
query is passed to Q.

fromsimon.queryimportQquery=Q(name='Simon')

The new object is then combined with one or more additional
Q objects, the end result of which is then passed
to find(). Q objects are
combined using bitwise and (&) and or (|) to represent logical
AND and OR, respectively.

# match users where name is equal to 'Simon' AND score is greater# than 1000users=User.find(Q(name='Simon')&Q(score__gt=1000))# match users where name is equal to 'Simon' AND score is greater# than 1000, OR name is either 'Alvin' or 'Theodore'users=User.find(Q(name='Simon',score__gt=1000)|Q(name__in=['Alvin','Theodore']))# match users who have no friendsusers=User.find(Q(friends__exists=False)|Q(friends__size=0))

Any number of Q objects can be chained together.
Be careful, however, as chaining together a lot of queries through
different operators can result in deeply nested queries, which may
become inefficient.

When using get() to retrieve a document, there are
two potential exceptions that may be raised. When one of these
exceptions is raised, it will be raised as part of the model class
being queried.

Assume the following documents for all examples below.

MultipleDocumentsFound

This exception is raised when multiple documents match the specified
query.

User.create(name='Simon',email='simon@example.com')User.create(name='Simon',email='simon@example.org')try:user=User.get(name='Simon')exceptUser.MultipleDocumentsFound:"""Handle the exception here"""else:"""Only one User was found"""

NoDocumentFound

This exception is raised when no documents match the specified query.

try:user=User.get(name='Alvin')exceptUser.NoDocumentFound:"""Handle the exception here"""else:"""Only one User was found"""

In the case of NoDocumentFound, there may be
times when the way to handle the exception would be to create the
document. A common pattern would:

Rather than making you use this pattern over and over, Simon does it for
you, inside the get_or_create() method. Not only will
get_or_create() do this, it will also let you know if
it had to create the document.

user,created=User.get_or_create(name='Simon')# user will be the newly created document and created will be Trueuser,created=User.get_or_create(name='Simon')# user will be loaded from the database and created will be False

If multiple documents match the query,
MultipleDocumentsFound will still be raised.