OPTIONS

$project (aggregation)

$project

Passes along the documents with only the specified fields to the next stage in the pipeline. The specified fields can be existing fields from the input documents or newly computed fields.

The $project stage has the following prototype form:

{ $project: { <specifications> } }

The $project takes a document that can specify the inclusion of fields, the suppression of the _id field, the addition of new fields, and the resetting the values of existing fields. The specifications have the following forms:

Syntax Description
<field>: <1 or true> Specify the inclusion of a field.
_id: <0 or false> Specify the suppression of the _id field.
<field>: <expression> Add a new field or reset the value of an existing field.

Include Existing Fields

  • The _id field is, by default, included in the output documents. To include the other fields from the input documents in the output documents, you must explicitly specify the inclusion in $project.
  • If you specify an inclusion of a field that does not exist in the document, $project ignores that field inclusion; i.e. $project does not add the field to the document.

Suppress the _id Field

The _id field is always included in the output documents by default. To exclude the _id field from the output documents, you must explicitly specify the suppression of the _id field in $project.

Add New Fields or Reset Existing Fields

To add a new field or to reset the value of an existing field, specify the field name and set its value to some expression. For more information on expressions, see Expressions.

To set a field value directly to a numeric or boolean literal, as opposed to setting the field to an expression that resolves to a literal, use the $literal operator. Otherwise, $project treats the numeric or boolean literal as a flag for including or excluding the field.

By specifying a new field and setting its value to the field path of an existing field, you can effectively rename a field.

Embedded Document Fields

When projecting or adding/resetting a field within an embedded document, you can either use dot notation, as in

"contact.address.country": <1 or 0 or expression>

Or you can nest the fields:

contact: { address: { country: <1 or 0 or expression> } }

When nesting the fields, you cannot use dot notation inside the embedded document to specify the field, e.g. contact: { "address.country": <1 or 0 or expression> } is invalid.

Examples

Include Specific Fields in Output Documents

Consider a books collection with the following document:

{
  "_id" : 1,
  title: "abc123",
  isbn: "0001122223334",
  author: { last: "zzz", first: "aaa" },
  copies: 5
}

The following $project stage includes only the _id, title, and the author fields in its output documents:

db.books.aggregate( [ { $project : { title : 1 , author : 1 } } ] )

The operation results in the following document:

{ "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }

Suppress _id Field in the Output Documents

The _id field is always included by default. To exclude the _id field from the output documents of the $project stage, specify the exclusion of the _id field by setting it to 0 in the projection document.

Consider a books collection with the following document:

{
  "_id" : 1,
  title: "abc123",
  isbn: "0001122223334",
  author: { last: "zzz", first: "aaa" },
  copies: 5
}

The following $project stage excludes the _id field but includes the title, and the author fields in its output documents:

db.books.aggregate( [ { $project : { _id: 0, title : 1 , author : 1 } } ] )

The operation results in the following document:

{ "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }

Include Specific Fields from Embedded Documents

Consider a bookmarks collection with the following documents:

{ _id: 1, user: "1234", stop: { title: "book1", author: "xyz", page: 32 } }
{ _id: 2, user: "7890", stop: [ { title: "book2", author: "abc", page: 5 }, { title: "b", author: "ijk", page: 100 } ] }

To include only the title field in the embedded document in the stop field, you can use the dot notation:

db.bookmarks.aggregate( [ { $project: { "stop.title": 1 } } ] )

Or, you can nest the inclusion specification in a document:

db.bookmarks.aggregate( [ { $project: { stop: { title: 1 } } } ] )

Both specifications result in the following documents:

{ "_id" : 1, "stop" : { "title" : "book1" } }
{ "_id" : 2, "stop" : [ { "title" : "book2" }, { "title" : "book3" } ] }

Include Computed Fields

Consider a books collection with the following document:

{
  "_id" : 1,
  title: "abc123",
  isbn: "0001122223334",
  author: { last: "zzz", first: "aaa" },
  copies: 5
}

The following $project stage adds the new fields isbn, lastName, and copiesSold:

db.books.aggregate(
   [
      {
         $project: {
            title: 1,
            isbn: {
               prefix: { $substr: [ "$isbn", 0, 3 ] },
               group: { $substr: [ "$isbn", 3, 2 ] },
               publisher: { $substr: [ "$isbn", 5, 4 ] },
               title: { $substr: [ "$isbn", 9, 3 ] },
               checkDigit: { $substr: [ "$isbn", 12, 1] }
            },
            lastName: "$author.last",
            copiesSold: "$copies"
         }
      }
   ]
)

The operation results in the following document:

{
   "_id" : 1,
   "title" : "abc123",
   "isbn" : {
      "prefix" : "000",
      "group" : "11",
      "publisher" : "2222",
      "title" : "333",
      "checkDigit" : "4"
   },
   "lastName" : "zzz",
   "copiesSold" : 5
}