$project in MongoDB - What is $project and how to use it in MongoDB

Introduction

In this article we’ll be discussing the stage of $project in MongoDB. We’ll explain it from the ground up so if you don’t know what a stage is please keep reading because we’ll cover that also.

Prerequisites

If you want to follow along with the demos you’ll need to have MongoDB installed on your system. You can either follow along through the MondoDB console or some interface like Compass Community.

The Pipeline Concept

The pipeline concept is similar to what you might be familiar with in the Unix Shell. You might execute a command and take that commands output as the input to the next command. It looks something like this in the Shell:

command_1 | command_2 | command_3 | .... | command_N

Where the output of command_1 is “piped” into command_2, whose output is “piped” into command_3 and so on.

This same concept exists within MongoDB’s aggregation. There are a set of stages, and each stage takes in a set of documents are outputs a set of documents. The output of one stage is used as the input to the next stage, same as in “piping”.

The stages that occur during aggregation are $project, $match, $group, $sort, $skip, $limit, and $unwind. Let’s take a look at what each one does starting with our focus $project.

  • $project − Selects specific fields
  • $match − Filters documents by some criteria
  • $group − Performs the actual aggregation
  • $sort − Sorts the documents by some criteria
  • $skip − Used to skip ahead in the array of documents
  • $limit − Limits the amount of documents returned
  • $unwind − This is a stage that deals with array fields and is a little hard to explain without visually seeing it, so please refer to the documentation if you’re curious about this field.

What’s done on the $project stage of aggregation

Let’s elaborate some more on what the $project stage does in aggregation. $project lets you specify what fields you want to have returned in the documents returned by your aggregation. This is not limited to existing fields but can include new fields that are computed.

How to Specify to Include a Field

To specify a field you want to include you can use this syntax:

<field>: true

or

<field>: 1

So if you want the firstname to be included in the documents, then you would use

firstname: true

or

firstname: 1

We think most developers learn by example so let’s jump straight into an example. Locally we have a sample database grocerydb for a small grocery store. Inside grocerydb is a products collection that contains the following three documents:

> use grocerydb
switched to db grocerydb
> db.products.find()
{
        "_id" : ObjectId("5d12c9974b74efae4662b8df"),
        "name" : "Soda",
        "quantity" : 10,
        "price" : 5.5
}
{
        "_id" : ObjectId("5d12c9a34b74efae4662b8e0"),
        "name" : "Bread",
        "quantity" : 9,
        "price" : 2.5
}
{
        "_id" : ObjectId("5d12c9b24b74efae4662b8e1"),
        "name" : "Milk",
        "quantity" : 4,
        "price" : 3.5
}

To use an aggregation and get the quantity field back we could use a query like this:

db.products.aggregate( [ { $project : { quantity : true } } ] )

Which would return:

{ "_id" : ObjectId("5d1a53765475803d1d2950b8"), "quantity" : 10 }
{ "_id" : ObjectId("5d1a53ce3eb9103d1d1a7981"), "quantity" : 9 }
{ "_id" : ObjectId("5d1a53d03eb9103d1d1a7982"), "quantity" : 4 }

How to Omit the _id field

Now you saw in the last example that even though the _id wasn’t specified in $project but was returned. This is because _id field is returned by default but you can omit the field by using this in your $project specification:

_id: false

or

_id: 0

Let’s see how we’d modify the last example to omit the id:

db.products.aggregate( [ { $project : { quantity : true, _id: false } } ] )

Which returns the following documents:

{ "quantity" : 10 }
{ "quantity" : 9 }
{ "quantity" : 4 }

How to Add a New Field

Now let’s try using $project to add a new field to our aggregation. For a simple example we’ll create a new field withTax for the price with sales tax at 8.25%. We’ll also add the name back in so you can verify the product with the price.

db.products.aggregate(
    [
    { $project :
        { name: true, quantity : true, _id: false, withTax: {$multiply: ["$price", 1.0825]} }
    }
    ]
)

This is the result:

{ "name" : "Soda", "quantity" : 10, "withTax" : 5.95375 }
{ "name" : "Bread", "quantity" : 9, "withTax" : 2.70625 }
{ "name" : "Milk", "quantity" : 4, "withTax" : 3.7887500000000003 }

Conclusion

We explained what $project does in aggregation and how to use it. We also went through an example of specifying a field, omitting the _id, and creating a computed field. We’ll leave it to you to explore using some of the other stages along with the $project stage to see what you can do.

If you want put your data and database management in the hands of someone you can trust, please don’t hesitate to reach out to us at Object Rocket.

Pilot the ObjectRocket Platform Free!

Try Fully-Managed CockroachDB, Elasticsearch, MongoDB, PostgreSQL (Beta) or Redis.

Get Started

Keep in the know!

Subscribe to our emails and we’ll let you know what’s going on at ObjectRocket. We hate spam and make it easy to unsubscribe.