In the previous module, we learned how to find exact matches using db.collection.find({ author: "George Orwell" }). While exact matches are useful, real-world applications require much more complex searches.
How do you find all books published after 1990? How do you find a book that is either Sci-Fi or Fantasy? How do you find a user who is missing an email address field entirely?
To solve these problems, MongoDB provides a rich set of Query Operators. You will always recognize an operator in MongoDB because it starts with a dollar sign ($).
1. Comparison Operators
Comparison operators allow you to compare the value of a field against a specific criteria (greater than, less than, not equal to, etc.).
Let’s assume we have a products collection with prices.
$eq (Equal To)
Matches values that are exactly equal. (This is usually implied, but you can write it explicitly).
// Implied
db.products.find({ price: 20 })
// Explicit Operator
db.products.find({ price: { $eq: 20 } })
$ne (Not Equal To)
Matches all values that are not equal to the specified value.
db.products.find({ category: { $ne: "Electronics" } })
$gt and $gte (Greater Than / Greater Than or Equal)
Used extensively for numbers and dates.
// Find products strictly more expensive than $50
db.products.find({ price: { $gt: 50 } })
// Find products $50 or more
db.products.find({ price: { $gte: 50 } })
$lt and $lte (Less Than / Less Than or Equal)
// Find products cheaper than $20
db.products.find({ price: { $lt: 20 } })
Range Queries
You can combine these operators in a single field to create a range!
// Find products priced between $20 and $50
db.products.find({ price: { $gte: 20, $lte: 50 } })
$in and $nin (In / Not In)
Matches any of the values specified in an array. This is perfect for categorizing searches without writing long OR statements.
// Find products that are either Laptops, Tablets, OR Phones
db.products.find({ category: { $in: ["Laptop", "Tablet", "Phone"] } })
// Find products that are NOT in those categories
db.products.find({ category: { $nin: ["Laptop", "Tablet", "Phone"] } })
2. Logical Operators
Logical operators allow you to combine multiple conditions together.
$and
Returns documents that match all the conditions. (Note: MongoDB implicitly applies an AND operation when you list multiple fields in a query object).
// Implicit AND (Standard way)
db.products.find({ category: "Laptop", price: { $lt: 1000 } })
// Explicit $and (Required if checking the same field twice)
db.products.find({
$and: [
{ category: "Laptop" },
{ price: { $lt: 1000 } }
]
})
$or
Returns documents that match at least one of the conditions.
// Find products that are EITHER Laptops OR cost less than $50
db.products.find({
$or: [
{ category: "Laptop" },
{ price: { $lt: 50 } }
]
})
$nor
Returns documents that fail all of the conditions.
// Find products that are NEITHER Laptops NOR cost more than $1000
db.products.find({
$nor: [
{ category: "Laptop" },
{ price: { $gt: 1000 } }
]
})
3. Element Operators
Because MongoDB is schema-less, documents in the same collection might have different fields. Element operators help you deal with this flexibility.
$exists
Finds documents where a specific field either exists or does not exist, regardless of its value.
// Find all users who DO NOT have a phone number field in their document
db.users.find({ phoneNumber: { $exists: false } })
$type
Selects documents where the value of a field is a specific BSON data type.
// Find all documents where the age field is stored as a string (e.g., "25" instead of 25)
db.users.find({ age: { $type: "string" } })
4. Evaluation Operators
These operators allow for more complex evaluations of data.
$regex
Allows you to perform powerful pattern matching using Regular Expressions.
// Find all users whose names start with the letter "J" (case-insensitive)
db.users.find({ name: { $regex: /^J/i } })
$expr
Allows you to use aggregation expressions within the query language. This is incredibly useful when you need to compare two fields within the same document against each other.
// Find products where the discount price is GREATER than the regular price (a pricing error!)
db.products.find({
$expr: { $gt: [ "$discountPrice", "$regularPrice" ] }
})
5. Array Operators
When your documents contain arrays (lists of items), querying them requires special tools.
$all
Matches arrays that contain all elements specified in the query, regardless of their order.
// Find a recipe that contains BOTH "Chicken" and "Garlic"
db.recipes.find({ ingredients: { $all: ["Chicken", "Garlic"] } })
$size
Matches any array with the exact specified number of elements.
// Find users who have exactly 3 items in their shopping cart
db.users.find({ cart: { $size: 3 } })
$elemMatch
This is arguably the most important array operator. If you have an array of objects, $elemMatch ensures that at least one single object in the array meets all the specified conditions simultaneously.
// Find a student who scored higher than 90 on a Math test
db.students.find({
grades: { $elemMatch: { subject: "Math", score: { $gt: 90 } } }
})
6. Bitwise Operators
Bitwise operators ($bitsAllClear, $bitsAllSet, $bitsAnyClear, $bitsAnySet) return documents based on bitmask conditions.
Note: You will rarely use these unless you are storing highly compressed binary flags (like file permissions or low-level sensor data) in your application.
Summary
The operators you learned in this module are the absolute bedrock of writing applications with MongoDB.
- Comparison Operators (
$gt,$lt,$in) let you filter numbers and lists. - Logical Operators (
$or,$and) let you combine multiple complex rules. - Element Operators (
$exists) help you manage schema-less inconsistencies. - Array Operators (
$all,$elemMatch) give you immense power over nested lists.
In the next module, we will step away from queries for a moment and look deeply at the Data Types that actually make up these fields!
Discussion
Loading comments...