Now that we have a grasp on the basics of querying array fields, we can tackle one more common scenario - querying embedded documents. It’s common for a collection to have an array of documents rather than individual values. For instance, take our tennis_players collection again, but now with a slightly different structure:

{ _id: ObjectId(...), name: "Miyu Kato", country: "Japan", wimbledon_doubles_placements: [{ year: 2016, place: 2 }, { year: 2017, place: 1 }, { year: 2018, place: 1 }, { year: 2019, place: 1 }] }

In the above example, we have an array field named wimbledon_doubles_placements that contains documents inside of it. There are two primary ways we can query the above collection: a match on an entire embedded document or a match based on a single field.

First, let’s see how we can do an exact match on the entire embedded document. For example, if we wanted to query our tennis_players collection for players who placed 2nd in 2019:

db.tennis_players.find( { "wimbledon_doubles_placements": { year: 2019, place: 2 } } )

In the above query, the field order must be exactly the order we are looking for, with the exact field values. This query would match the below document because the order and values are exactly the same as the one in the query:

{ _id: ObjectId(...), name: "Gabriela Dabrowski", country: "Canada", wimbledon_doubles_placements: [{ year: 2019, place: 2 }] }, { _id: ObjectId(...), name: "Yifan Xu", country: “China”, wimbledon_doubles_placements: [{ year: 2019, place: 2 }] }…

However, a query like this:

db.tennis_players.find( { "wimbledon_doubles_placements": {place: 2, year: 2019 } } )

Would not return any results since there would be no documents with that specific ordering.

We can also query based on a single field. For example, if we just wanted to query for any Wimbledon doubles winners in the year 2016, we can do the following: 

db.tennis_players.find( { "wimbledon_doubles_placements.year": 2016 )

Notice that the syntax is exactly the same as when we were querying for non-array fields. The embedded document field and parent document field must be wrapped in quotation marks (single or double) and use the dot (.) notation. This query would return results like the following: 

{ _id: ObjectId(...), name: "Tímea Babos", country: "Hungary", wimbledon_doubles_placements: [{ year: 2015, place: 4 }, { year: 2016, place: 2 }] { _id: ObjectId(...), name: "Yaroslava Shvedova", country: "Kazakhstan", wimbledon_doubles_placements: [{ year: 2010, place: 1 }, { year: 2016, place: 2 }] }…

Here, our query result has all the documents that have an embedded document with a year field with the value of 2016.

It’s important to note we can even combine these queries with query operators and even do multiple query conditions using $elemMatch. For more examples, take a look at the official MongoDB documentation on querying embedded documents in arrays.

Before we wrap up, let’s practice querying the embedded documents in our restaurants collection!



Connect to the restaurants database. Then, search the listingsAndReviews collection for a restaurant that has the following embedded document inside of the grades field:

{ date: ISODate("2014-07-11T00:00:00.000Z"), grade: 'A', score: 8 }

Now, let’s search the listingsAndReviews collection for a restaurant based on a single embedded field. Query the collection and find all the restaurants that have embedded documents in the grades field with a grade of "C".

Take this course for free

Mini Info Outline Icon
By signing up for Codecademy, you agree to Codecademy's Terms of Service & Privacy Policy.

Or sign up using:

Already have an account?