Skip to main content

MongoDB Logical Operators

In MongoDB, logical operators allow you to create complex query conditions by combining multiple expressions. These operators help you filter documents based on multiple criteria, giving you precise control over which documents are returned in your query results.

Introduction

When querying a MongoDB database, you'll often need to filter data based on multiple conditions. For example, you might want to find all products that are either in stock AND on sale, or products that are neither in stock NOR on sale. This is where logical operators become essential.

MongoDB provides four main logical operators:

  1. $and: Returns documents that match all specified conditions
  2. $or: Returns documents that match at least one of the specified conditions
  3. $not: Returns documents that do not match the specified condition
  4. $nor: Returns documents that fail to match all specified conditions

Let's explore each of these operators in detail with practical examples.

The $and Operator

The $and operator performs a logical AND operation on an array of expressions and returns documents that satisfy all the expressions.

Syntax

javascript
{ $and: [ { <expression1> }, { <expression2> }, ... ] }

Basic Example

Let's say we have a collection of products and want to find all products that are both in stock and priced under $100:

javascript
db.products.find({
$and: [
{ inStock: true },
{ price: { $lt: 100 } }
]
})

This query returns documents where both conditions are true: inStock is true and price is less than 100.

Implicit AND Operations

MongoDB actually performs an implicit AND operation when you provide multiple key-value pairs in a query document. So the previous query could be simplified to:

javascript
db.products.find({
inStock: true,
price: { $lt: 100 }
})

Both queries return the same results. However, the explicit $and operator becomes necessary when you need to include the same field or operator more than once in a query.

When to Use Explicit $and

For example, if you want to find products with prices between 10and10 and 100, but also excluding exactly $50:

javascript
db.products.find({
$and: [
{ price: { $gt: 10 } },
{ price: { $lt: 100 } },
{ price: { $ne: 50 } }
]
})

In this case, you can't use implicit AND because you're specifying multiple conditions for the same price field.

The $or Operator

The $or operator performs a logical OR operation on an array of expressions and returns documents that satisfy at least one of the expressions.

Syntax

javascript
{ $or: [ { <expression1> }, { <expression2> }, ... ] }

Basic Example

Let's find all products that are either on sale OR have a high customer rating:

javascript
db.products.find({
$or: [
{ onSale: true },
{ customerRating: { $gte: 4.5 } }
]
})

This query returns documents where either onSale is true OR customerRating is greater than or equal to 4.5 (or both).

Practical Example

Finding products that meet specific customer search criteria:

javascript
db.products.find({
$or: [
{ category: "electronics" },
{ tags: "technology" },
{ name: { $regex: "phone", $options: "i" } }
]
})

This query finds products that are either in the "electronics" category, have a "technology" tag, or have "phone" in their name (case insensitive).

The $not Operator

The $not operator performs a logical NOT operation on the specified expression and returns documents that do not match the expression.

Syntax

javascript
{ field: { $not: { <operator-expression> } } }

Basic Example

Find all products that are not priced above $100:

javascript
db.products.find({
price: { $not: { $gt: 100 } }
})

This query returns documents where the price is not greater than 100 (which means it's either less than or equal to 100, or the price field doesn't exist).

Practical Example

Find documents that don't match a regular expression:

javascript
db.products.find({
description: { $not: { $regex: "limited edition", $options: "i" } }
})

This returns products whose descriptions do not contain the phrase "limited edition".

The $nor Operator

The $nor operator performs a logical NOR operation on an array of expressions and returns documents that fail to match all of the expressions.

Syntax

javascript
{ $nor: [ { <expression1> }, { <expression2> }, ... ] }

Basic Example

Find products that are neither out of stock nor on sale:

javascript
db.products.find({
$nor: [
{ inStock: false },
{ onSale: true }
]
})

This query returns documents where both expressions are false (meaning inStock is not false and onSale is not true).

Practical Example

Filtering out multiple unwanted categories:

javascript
db.products.find({
$nor: [
{ category: "clothing" },
{ category: "accessories" },
{ price: { $lt: 20 } }
]
})

This query returns products that are not in the "clothing" or "accessories" categories and don't have a price less than 20.

Combining Logical Operators

You can nest logical operators to create more complex queries.

Example: Combining $and and $or

Find products that are either:

  • In the "electronics" category AND priced under $500, OR
  • In the "books" category AND have a rating of at least 4 stars
javascript
db.products.find({
$or: [
{
$and: [
{ category: "electronics" },
{ price: { $lt: 500 } }
]
},
{
$and: [
{ category: "books" },
{ rating: { $gte: 4 } }
]
}
]
})

Real-World Application: E-commerce Filtering

Let's look at a practical example for an e-commerce website where users can filter products with multiple criteria:

javascript
db.products.find({
$and: [
{ category: "smartphones" },
{
$or: [
{ brand: "Apple" },
{ brand: "Samsung" }
]
},
{
$and: [
{ price: { $gte: 500 } },
{ price: { $lte: 1000 } }
]
},
{
$or: [
{ features: "waterproof" },
{ features: "5G" }
]
},
{
$nor: [
{ status: "discontinued" },
{ inStock: false }
]
}
]
})

This query finds:

  • Smartphones
  • Made by Apple or Samsung
  • Priced between 500and500 and 1000
  • That have either "waterproof" or "5G" features
  • That are not discontinued and are in stock

For a user management system where you need to find specific users matching complex criteria:

javascript
db.users.find({
$and: [
{ "account.status": "active" },
{
$or: [
{ role: "admin" },
{
$and: [
{ role: "editor" },
{ "permissions.canPublish": true }
]
}
]
},
{
$nor: [
{ lastLogin: { $lt: new Date(Date.now() - 30 * 24 * 60 * 60 * 1000) } }, // Not logged in for 30 days
{ "security.mfaEnabled": false } // No MFA enabled
]
}
]
})

This query finds:

  • Active users
  • Who are either admins OR editors with publishing permissions
  • Who have logged in within the last 30 days AND have MFA enabled

Performance Considerations

When using logical operators, keep these performance tips in mind:

  1. Use indexes for fields involved in your queries whenever possible
  2. Place the most selective conditions first in $and operations
  3. For $or queries, each condition should be indexable for best performance
  4. Complex queries with many logical operators may benefit from the aggregation pipeline for better performance

Summary

MongoDB's logical operators provide powerful tools for creating complex queries:

  • Use $and when all conditions must be met
  • Use $or when at least one condition must be met
  • Use $not to negate a specific condition
  • Use $nor when none of the conditions should be met

By combining these operators, you can create highly specific queries that precisely target the documents you need. This ability to filter data with complex conditions is essential for building flexible and powerful applications with MongoDB.

Practice Exercises

  1. Write a query that finds all products in the "electronics" category with a price between 100and100 and 500 and that have at least a 4-star rating.

  2. Create a query that finds users who are either premium members OR have made at least 5 purchases, AND have been customers for more than a year.

  3. Find all orders that were neither placed on a weekend NOR have a status of "cancelled", AND have a total amount greater than $50.

Additional Resources

Remember that mastering logical operators is key to writing effective MongoDB queries that can handle real-world data filtering requirements.



If you spot any mistakes on this website, please let me know at [email protected]. I’d greatly appreciate your feedback! :)