Querying Nested Fields in MongoDB
In MongoDB, documents can contain nested objects (also called embedded documents). To query such data, you use a concept called dot notation.
This allows you to target specific fields inside a nested document or even elements inside an array of documents.
Understanding Nested Fields
Let’s say you have a collection called employees
and each document contains an embedded address
object:
db.employees.insertMany([
{
name: "Alice",
age: 28,
address: {
city: "New York",
zip: "10001"
}
},
{
name: "Bob",
age: 35,
address: {
city: "San Francisco",
zip: "94105"
}
}
]);
Q: How can we find all employees living in New York?
A: We can use dot notation to query the nested address.city
field.
Querying a Nested Field
db.employees.find({ "address.city": "New York" });
Output:
{ _id: ObjectId("..."), name: "Alice", age: 28, address: { city: "New York", zip: "10001" } }
Explanation: Using "address.city"
, we told MongoDB to look inside the address
object and match the city
field value.
Querying Nested Fields with Conditions
Let’s query for employees whose ZIP code is greater than "90000":
db.employees.find({ "address.zip": { $gt: "90000" } });
Output:
{ _id: ObjectId("..."), name: "Bob", age: 35, address: { city: "San Francisco", zip: "94105" } }
Q: Can I use comparison operators like $gt
and $lt
on nested fields?
A: Yes! You can use them just like on top-level fields.
Querying Arrays of Nested Documents
Consider a new collection called students
, where each student has an array of grades
, each with a subject and score:
db.students.insertMany([
{
name: "John",
grades: [
{ subject: "Math", score: 85 },
{ subject: "English", score: 78 }
]
},
{
name: "Sara",
grades: [
{ subject: "Math", score: 92 },
{ subject: "Science", score: 88 }
]
}
]);
Query a Nested Field Inside an Array
Let’s find students who scored more than 90 in Math:
db.students.find({ "grades.subject": "Math", "grades.score": { $gt: 90 } });
Output:
{ _id: ObjectId("..."), name: "Sara", grades: [ { subject: "Math", score: 92 }, { subject: "Science", score: 88 } ] }
Explanation: This query checks all grades
documents inside the array to find one where subject
is "Math" and score
is greater than 90. MongoDB automatically traverses the array for matching objects.
Using $elemMatch
for Precision
The previous query may return a document where subject
and score
match in different array elements. To ensure both conditions apply to the same array element, use $elemMatch
:
db.students.find({
grades: { $elemMatch: { subject: "Math", score: { $gt: 90 } } }
});
Output:
{ _id: ObjectId("..."), name: "Sara", grades: [ { subject: "Math", score: 92 }, { subject: "Science", score: 88 } ] }
Explanation: $elemMatch
ensures that both subject: "Math"
and score: { $gt: 90 }
are part of the same object inside the grades
array.
Recap: Dot Notation and Nested Queries
- Use dot notation (e.g.,
"address.city"
) to access nested fields. - Dot notation works on objects and arrays of objects.
- Use
$elemMatch
for matching multiple conditions in a single object within an array.
Next Up
Now that you know how to query nested documents, let’s move on to learn about pagination using limit()
, skip()
, and sort()
to manage large result sets.