Lesson 1
Using Projection for Clarity and Focus
Introduction

Welcome to the first lesson of the course "A Closer Look at Read Operations". This course builds upon the foundations laid out in previous courses, where you learned the basic concepts of MongoDB, CRUD operations, data modeling, and relationships. In this course, we will focus exclusively on read operations and data retrieval, specifically tackling complex retrieval scenarios. In this lesson, we will delve into projection.

What is Projection?

Projection in MongoDB allows you to specify which fields you want to include or exclude in your query results. This can be crucial for performance and efficiency, especially when dealing with large documents, as it reduces the amount of data transmitted over the wire. Instead of retrieving the entire document, you can hone in on just the information you need.

For example, consider this document:

1{ 2 "title": "The Amazing Spider-Man", 3 "issue_number": 1, 4 "published_year": 1963, 5 "genres": ["Action", "Adventure", "Superhero"], 6 "writer": { "name": "Stan Lee", "nationality": "American" }, 7 "artist": { "name": "Steve Ditko", "nationality": "American" }, 8 "characters": [ 9 { "name": "Spider-Man", "alter_ego": "Peter Parker", "abilities": ["Super strength", "Wall-crawling", "Spider-sense"] }, 10 { "name": "J. Jonah Jameson", "role": "Editor-in-Chief of the Daily Bugle" }, 11 { "name": "Aunt May", "role": "Peter Parker's Aunt" } 12 ], 13 "publisher": { "name": "Marvel Comics", "location": "New York" }, 14 "related_comics": [ "Spider-Man: Blue", "Ultimate Spider-Man", "Spider-Verse" ] 15}

If your application only needs the title and published_year for a listing page, there’s no need to retrieve the entire document.

Syntax Explained

Let's use the findOne method to demonstrate projection. Imagine that you want to retrieve a document from the comic_books collection, but you are only interested in the title and published_year fields. Here's the query you can use:

JavaScript
1use comic_book_store_db 2 3db.comic_books.findOne({}, { title: 1, published_year: 1, _id: 0 })

This query will return the first document in the collection with the specified fields only:

1{ "title": "The Amazing Spider-Man", "published_year": 1963 }

In this query, the first argument to the findOne method is the query filter, represented by an empty object {}, which matches all documents in the collection. The second argument is the projection object { title: 1, published_year: 1, _id: 0 }. Here, title: 1 and published_year: 1 specify that these fields should be included in the result, while _id: 0 indicates that the _id field should be excluded from the result. By default, MongoDB includes the _id field in the output, so explicitly excluding it is necessary if you don't need it. Instead of using 1 to include and 0 to exclude fields, you can also use true and false, respectively.

Projection Pitfalls

There are two types of projection in MongoDB: including and excluding. You cannot mix these two types within the same query, except for the _id field, which is a special case.

  • Including projection: Specify the fields you want to include.
  • Excluding projection: Specify the fields you want to exclude.

Below are a few usage examples:

JavaScript
1use comic_book_store_db 2 3// This will include only the `title` and `published_year` fields in the result 4// Note that `_id` is included by default unless explicitly excluded. 5db.comic_books.findOne({}, { title: 1, published_year: 1 }) 6 7// This will exclude the `writer` and `artist` fields from the result, including all other fields 8db.comic_books.findOne({}, { writer: 0, artist: 0 }) 9 10// This will include only the `title` and `published_year` fields and exclude the `_id` field 11db.comic_books.findOne({}, { title: 1, published_year: 1, _id: 0 }) 12 13// Mixing inclusion and exclusion projection types (except for `_id`) is not allowed 14// db.comic_books.findOne({}, { title: 1, published_year: 1, writer: 0 }) // Uncomment to see the error
Applying Projection to Nested Documents

Projection is not limited to top-level fields; you can also apply it to fields within nested documents. For instance, to retrieve only the writer’s name and nationality, utilize the following query:

JavaScript
1use comic_book_store_db 2 3db.comic_books.findOne({}, { "writer.name": 1, "writer.nationality": 1, _id: 0 })

Note: Quotes are necessary for nested fields because otherwise, the . would cause an error.

The query above will return the following document:

1{ 2 "writer": { 3 "name": "Stan Lee", 4 "nationality": "American" 5 } 6}
Projecting Arrays of Documents

Similarly to nested documents, you can project specific fields of documents within an array. For example, the following query projects the characters array and includes only the character names:

JavaScript
1use comic_book_store_db 2 3db.comic_books.findOne({}, { "characters.name": 1, _id: 0 })

The output of this query will be as follows:

1{ 2 "characters": [ 3 { "name": "Spider-Man" }, 4 { "name": "J. Jonah Jameson" }, 5 { "name": "Aunt May" } 6 ] 7}
Summary

In this lesson, we've introduced the concept of projection in MongoDB and explained why it’s useful for efficient data retrieval. We've covered the basics of including and excluding fields, examined potential pitfalls, and demonstrated how to apply projection to nested fields and arrays. Understanding these concepts is vital for effective data querying and optimizing the performance of your application. Continue practicing these skills in the subsequent lessons and exercises to master MongoDB read operations. Happy coding!

Enjoy this lesson? Now it's time to practice with Cosmo!
Practice is how you turn knowledge into actual skills.