A compound query is a query that combines multiple conditions (filters) using logical operators such as $and
, $or
, $nor
, and $not
.
$and
OperatorThe $and
operator allows you to combine multiple conditions, and it is the default behavior when you pass multiple fields in a query. However, if you want to be explicit, you can use $and
.
Example (find users who are older than 25 and live in New York):
javascript
Copy code
db.users.find({ $and: [ { age: { $gt: 25 } }, { city: "New York" } ] });
$or
OperatorThe $or
operator returns documents that match any of the specified conditions.
Example (find users who are either older than 30 or live in New York):
javascript
Copy code
db.users.find({ $or: [ { age: { $gt: 30 } }, { city: "New York" } ] });
$nor
OperatorThe $nor
operator is the inverse of $or
. It returns documents that do not match any of the given conditions.
Example (find users who are not older than 25 or do not live in New York):
javascript
Copy code
db.users.find({ $nor: [ { age: { $gt: 25 } }, { city: "New York" } ] });
$not
OperatorThe $not
operator is used to negate a query condition.
Example (find users who are not older than 25):
javascript
Copy code
db.users.find({ age: { $not: { $gt: 25 } } });
MongoDB supports regular expression (regex) queries to perform pattern matching in string fields.
Example (find users whose names start with ‘John’):
javascript
Copy code
db.users.find({ name: /^John/ });
Here, ^John
matches any string that starts with “John”.
To make a regex query case-insensitive, you can use the i
option.
Example (find users whose names start with ‘john’ regardless of case):
javascript
Copy code
db.users.find({ name: /^john/i });
$options
OperatorYou can also use the $options
operator to specify flags (e.g., case-insensitivity) in the query.
Example (case-insensitive search for names containing ‘doe’):
javascript
Copy code
db.users.find({ name: { $regex: "doe", $options: "i" } });
MongoDB supports geospatial indexing and querying, allowing you to find documents based on location (latitude/longitude) or proximity.
For basic 2D geospatial queries (used for flat Cartesian coordinates), MongoDB provides $geoWithin
and $near
operators.
Example (find documents within a given polygon):
javascript
Copy code
db.places.find({ location: { $geoWithin: { $geometry: { type: "Polygon", coordinates: [[[-73.97, 40.77], [-73.99, 40.75], [-74.00, 40.77]]] } } } });
The 2dsphere index is used for querying spherical data (i.e., latitude/longitude on the globe). You can use $nearSphere
and $geoWithin
operators with this index.
Example (find places near a specific point using the 2dsphere index):
javascript
Copy code
db.places.find({ location: { $nearSphere: { $geometry: { type: "Point", coordinates: [-73.97, 40.77] }, $maxDistance: 5000 } } });
This will find places within 5km (5000 meters) of the specified coordinates.
MongoDB supports rich querying capabilities for arrays, allowing you to filter and manipulate arrays within documents.
To match documents where an array contains a specific value, use the field: value
syntax.
Example (find users with a specific tag in their tags
array):
javascript
Copy code
db.users.find({ tags: "admin" });
$all
OperatorThe $all
operator allows you to query documents where an array field contains all of the specified elements, regardless of order.
Example (find users who have both “admin” and “editor” tags):
javascript
Copy code
db.users.find({ tags: { $all: ["admin", "editor"] } });
$elemMatch
OperatorThe $elemMatch
operator is useful for querying arrays of objects when you want to match multiple conditions within a single element of an array.
Example (find orders where the items
array has a quantity
greater than 5 and a price
less than 100):
javascript
Copy code
db.orders.find({ items: { $elemMatch: { quantity: { $gt: 5 }, price: { $lt: 100 } } } });
Projection operators allow you to control which fields are returned in the query result, providing more efficient data retrieval.
$
You can include specific fields in your query result by specifying them in the projection.
Example (return only the name
and age
fields of users):
javascript
Copy code
db.users.find({}, { name: 1, age: 1 });
You can also exclude fields from the result using 0
.
Example (exclude the address
field from the results):
javascript
Copy code
db.users.find({}, { address: 0 });
$slice
with ArraysThe $slice
operator allows you to limit the number of elements returned in an array field.
Example (get the first 3 tags for each user):
javascript
Copy code
db.users.find({}, { tags: { $slice: 3 } });
$elemMatch
in ProjectionUse $elemMatch
in projections to return specific elements from an array.
Example (get the first order
with quantity greater than 5 from the orders
array):
javascript
Copy code
db.users.find({}, { orders: { $elemMatch: { quantity: { $gt: 5 } } } });
MongoDB supports text search, allowing you to search for text patterns within string fields. Before using text search, ensure that a text index is created on the field.
javascript
Copy code
db.products.createIndex({ description: "text" });
Once a text index is created, you can perform text search queries using the $text
operator.
Example (search for products containing the word “laptop”):
javascript
Copy code
db.products.find({ $text: { $search: "laptop" } });
$language
You can specify the language for the text search to improve results based on linguistic rules.
Example (search for “laptop” with English language processing):
javascript
Copy code
db.products.find({ $text: { $search: "laptop", $language: "en" } });
Many advanced querying techniques involve using the Aggregation Framework, which allows you to perform operations such as filtering, grouping, sorting, and reshaping data.
Example (group users by city and calculate the total amount spent):
javascript
Copy code
db.users.aggregate([ { $group: { _id: "$city", totalAmountSpent: { $sum: "$amountSpent" } } } ]);
$facet
for Multiple PipelinesThe $facet
operator allows you to run multiple pipelines within a single aggregation query.
Example (aggregate user data with multiple pipelines):
javascript
Copy code
db.users.aggregate([ { $facet: { "ageStats": [ { $group: { _id: null, avgAge: { $avg: "$age" }, maxAge: { $max: "$age" } } } ], "locationStats": [ { $group: { _id: "$city", count: { $sum: 1 } } } ] } } ]);
As your queries become more complex, it’s important to focus on performance. MongoDB provides several techniques to optimize queries.
$match
, $sort
, and $lookup
.$limit
as early as possible in the pipeline to reduce the amount of data processed.$or
with large datasets: $or
queries can be slower; consider breaking them into separate queries or using compound indexes.