Sling Academy
Home/Python/MongoEngine: Filter Documents by Multiple Fields

MongoEngine: Filter Documents by Multiple Fields

Last updated: February 10, 2024

MongoEngine, a Document-Object Mapper (or simply ODM), bridges the gap between the document-oriented MongoDB database and Python applications. This tutorial delves into filtering documents by multiple fields using MongoEngine, an essential capability for querying complex data sets effectively.

Getting Started

Before diving into complex queries, ensure you have MongoEngine installed and a MongoDB instance running. You can install MongoEngine via pip:

pip install mongoengine

Connect to your MongoDB instance:

from mongoengine import connect
connect('your_database_name', host='localhost', port=27017)

Define a simple document:

from mongoengine import *

class Employee(Document):
    name = StringField(required=True)
    age = IntField(required=True)
    department = StringField(required=True)

Basic Filtering

To filter documents based on a single field, you can use the following approach. However, this tutorial focuses on more complex scenarios where multiple fields are involved:

employees = Employee.objects(age__gt=30, department='HR')

The above query fetches employees aged over 30 from the HR department. The double underscore (__gt) represents a “greater than” comparison.

Combining Filters

The real power of MongoEngine’s querying capabilities shine when you start combining filters to meet more complex criteria. Here are several ways to accomplish this:

Using Q Objects

Q objects allow for the construction of complex query expressions. They can be combined using | (OR) and & (AND) operators:

from mongoengine.queryset.visitor import Q

query = Employee.objects(Q(age__gt=30) & Q(department='HR'))
for emp in query:
    print(emp.name)

This combines two conditions: employees older than 30 in the HR department.

Chaining Filters

Alternatively, you can chain filter calls to achieve a similar effect:

result = Employee.objects(age__gt=30).filter(department='HR')
for r in result:
    print(r.name)

Though subtly different, chaining filters can sometimes offer clearer syntax for complex queries.

Advanced Filtering

For more advanced queries, involving nested documents or arrays, the querying syntax becomes more interesting:

Nested Documents

Assuming an Employee document now has an nested Address document:

class Address(EmbeddedDocument):
    street = StringField()
    city = StringField()

class Employee(Document):
    name = StringField(required=True)
    age = IntField(required=True)
    address = EmbeddedDocumentField(Address)

To filter employees based on their city:

employees = Employee.objects(address__city='New York')

This takes advantage of the dot notation to access fields within an embedded document.

Involving Arrays

If an employee can belong to multiple departments, the model and filtering adapt:

class Employee(Document):
    name = StringField(required=True)
    age = IntField(required=True)
    departments = ListField(StringField())

employees = Employee.objects(departments__in=['HR', 'IT'])

This time, the “__in” operator retrieves employees belonging to either HR or IT departments.

Conclusion

Through MongoEngine, Python developers have a powerful tool for constructing complex queries against MongoDB data sets. From simple field matching to intricate expressions involving logical operators, embedded documents, and arrays, MongoEngine supports a wide array of querying functions. Mastering these capabilities empowers developers to retrieve precisely the data they need, fostering efficient and effective application development.

Next Article: MongoEngine: How to update embedded documents

Previous Article: MongoEngine: AND & OR Conditions – Tutorial & Examples

Series: Data Persistence in Python – Tutorials & Examples

Python

You May Also Like

  • Introduction to yfinance: Fetching Historical Stock Data in Python
  • Monitoring Volatility and Daily Averages Using cryptocompare
  • Advanced DOM Interactions: XPath and CSS Selectors in Playwright (Python)
  • Automating Strategy Updates and Version Control in freqtrade
  • Setting Up a freqtrade Dashboard for Real-Time Monitoring
  • Deploying freqtrade on a Cloud Server or Docker Environment
  • Optimizing Strategy Parameters with freqtrade’s Hyperopt
  • Risk Management: Setting Stop Loss, Trailing Stops, and ROI in freqtrade
  • Integrating freqtrade with TA-Lib and pandas-ta Indicators
  • Handling Multiple Pairs and Portfolios with freqtrade
  • Using freqtrade’s Backtesting and Hyperopt Modules
  • Developing Custom Trading Strategies for freqtrade
  • Debugging Common freqtrade Errors: Exchange Connectivity and More
  • Configuring freqtrade Bot Settings and Strategy Parameters
  • Installing freqtrade for Automated Crypto Trading in Python
  • Scaling cryptofeed for High-Frequency Trading Environments
  • Building a Real-Time Market Dashboard Using cryptofeed in Python
  • Customizing cryptofeed Callbacks for Advanced Market Insights
  • Integrating cryptofeed into Automated Trading Bots