$project (aggregation)
Definition
$project
- Passes along the documents with the requested fields to thenext stage in the pipeline. The specified fields can be existingfields from the input documents or newly computed fields.
The $project
stage has the following prototype form:
- { $project: { <specification(s)> } }
The $project
takes a document that can specify theinclusion of fields, the suppression of the _id
field,the addition of new fields, and the resetting of the values of existingfields. Alternatively, you may specify the _exclusion_of fields.
The $project
specifications have the following forms:
FormDescription<field>: <1 or true>
Specifies the inclusion of a field._id: <0 or false>
Specifies the suppression of the _id
field.
To exclude a field conditionally, use the REMOVE
variable instead. For details, see Exclude Fields Conditionally.<field>: <expression>
Adds a new field or resets the value of an existing field.
Changed in version 3.6: MongoDB 3.6 adds the variable REMOVE
. If thethe expression evaluates to $$REMOVE
, the field isexcluded in the output. For details, see Exclude Fields Conditionally.
<field>:<0 or false>
Specifies the exclusion of a field.
To exclude a field conditionally, use the REMOVE
variable instead. For details, see Exclude Fields Conditionally.
If you specify the exclusion of a field other than _id
,you cannot employ any other $project
specification forms. This restriction does not apply toconditionally exclusion of a field using the REMOVE
variable.
See also the $unset
stage to exclude fields.
Considerations
Include Existing Fields
- The
_id
field is, by default, included in the output documents.To include any other fields from the input documents in the outputdocuments, you must explicitly specify the inclusion in$project
. - If you specify an inclusion of a field that does not exist in thedocument,
$project
ignores that field inclusion anddoes not add the field to the document.
Suppress the _id Field
By default, the _id
field is included in the output documents.To exclude the _id
field from the output documents, youmust explicitly specify the suppression of the _id
field in$project
.
Exclude Fields
New in version 3.4.
If you specify the exclusion of a field or fields, all other fields arereturned in the output documents.
- { $project: { "<field1>": 0, "<field2>": 0, ... } } // Return all but the specified fields
If you specify the exclusion of a field other than _id
, you cannotemploy any other $project
specification forms: i.e. if youexclude fields, you cannot also specify the inclusion of fields, resetthe value of existing fields, or add new fields. This restriction doesnot apply to conditional exclusion of a field using theREMOVE
variable.
See also the $unset
stage to exclude fields.
Exclude Fields Conditionally
New in version 3.6.
Starting in MongoDB 3.6, you can use the variable REMOVE
inaggregation expressions to conditionally suppress a field. For anexample, see Conditionally Exclude Fields.
Add New Fields or Reset Existing Fields
Note
MongoDB also provides $addFields
to add new fields tothe documents.
To add a new field or to reset the value of an existing field, specifythe field name and set its value to some expression. For moreinformation on expressions, see Expressions.
Literal Values
To set a field value directly to a numeric or boolean literal, asopposed to setting the field to an expression that resolves to aliteral, use the $literal
operator. Otherwise,$project
treats the numeric or boolean literal as a flagfor including or excluding the field.
Field Rename
By specifying a new field and setting its value to the field path of anexisting field, you can effectively rename a field.
New Array Fields
Starting in MongoDB 3.2, $project
stage supports using thesquare brackets []
to directly create new array fields. If arrayspecification includes fields that are non-existent in a document, theoperation substitutes null
as the value for that field. For anexample, see Project New Array Fields.
Embedded Document Fields
When projecting or adding/resetting a field within an embeddeddocument, 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 theembedded document to specify the field, e.g. contact: {"address.country": <1 or 0 or expression> }
is invalid.
Restrictions
Changed in version 3.4.
MongoDB 3.4 and later produces an error if the $project
specification is an empty document.
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
inthe 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 butincludes the title
, and the author
fields in its outputdocuments:
- db.books.aggregate( [ { $project : { _id: 0, title : 1 , author : 1 } } ] )
The operation results in the following document:
- { "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }
Exclude Fields from Output Documents
New in version 3.4.
Consider a books
collection with the following document:
- {
- "_id" : 1,
- title: "abc123",
- isbn: "0001122223334",
- author: { last: "zzz", first: "aaa" },
- copies: 5,
- lastModified: "2016-07-28"
- }
The following $project
stage excludes the lastModified
field from the output:
- db.books.aggregate( [ { $project : { "lastModified": 0 } } ] )
See also the $unset
stage to exclude fields.
Exclude Fields from Embedded Documents
New in version 3.4.
Consider a books
collection with the following document:
- {
- "_id" : 1,
- title: "abc123",
- isbn: "0001122223334",
- author: { last: "zzz", first: "aaa" },
- copies: 5,
- lastModified: "2016-07-28"
- }
The following $project
stage excludes the author.first
and lastModified
fields from the output:
- db.books.aggregate( [ { $project : { "author.first" : 0, "lastModified" : 0 } } ] )
Alternatively, you can nest the exclusion specification in a document:
- db.bookmarks.aggregate( [ { $project: { "author": { "first": 0}, "lastModified" : 0 } } ] )
Both specifications result in the same output:
- {
- "_id" : 1,
- "title" : "abc123",
- "isbn" : "0001122223334",
- "author" : {
- "last" : "zzz"
- },
- "copies" : 5,
- }
See also the $unset
stage to exclude fields.
Conditionally Exclude Fields
New in version 3.6.
Starting in MongoDB 3.6, you can use the variable REMOVE
inaggregation expressions to conditionally suppress a field.
Consider a books
collection with the following document:
- {
- "_id" : 1,
- title: "abc123",
- isbn: "0001122223334",
- author: { last: "zzz", first: "aaa" },
- copies: 5,
- lastModified: "2016-07-28"
- }
- {
- "_id" : 2,
- title: "Baked Goods",
- isbn: "9999999999999",
- author: { last: "xyz", first: "abc", middle: "" },
- copies: 2,
- lastModified: "2017-07-21"
- }
- {
- "_id" : 3,
- title: "Ice Cream Cakes",
- isbn: "8888888888888",
- author: { last: "xyz", first: "abc", middle: "mmm" },
- copies: 5,
- lastModified: "2017-07-22"
- }
The following $project
stage uses the REMOVE
variable to excludes the author.middle
field only if it equals ""
:
- db.books.aggregate( [
- {
- $project: {
- title: 1,
- "author.first": 1,
- "author.last" : 1,
- "author.middle": {
- $cond: {
- if: { $eq: [ "", "$author.middle" ] },
- then: "$$REMOVE",
- else: "$author.middle"
- }
- }
- }
- }
- ] )
The aggregation operation results in the following output:
- { "_id" : 1, "title" : "abc123", "author" : { "last" : "zzz", "first" : "aaa" } }
- { "_id" : 2, "title" : "Baked Goods", "author" : { "last" : "xyz", "first" : "abc" } }
- { "_id" : 3, "title" : "Ice Cream Cakes", "author" : { "last" : "xyz", "first" : "abc", "middle" : "mmm" } }
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: "book3", author: "ijk", page: 100 } ] }
To include only the title
field in the embedded document in thestop
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 fieldsisbn
, 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
- }
Project New Array Fields
For example, if a collection includes the following document:
- { "_id" : ObjectId("55ad167f320c6be244eb3b95"), "x" : 1, "y" : 1 }
The following operation projects the fields x
and y
as elementsin a new field myArray
:
- db.collection.aggregate( [ { $project: { myArray: [ "$x", "$y" ] } } ] )
The operation returns the following document:
- { "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1 ] }
If array specification includes fields that are non-existent in adocument, the operation substitutes null
as the value for thatfield.
For example, given the same document as above, the following operationprojects the fields x
, y
, and a non-existing field$someField
as elements in a new field myArray
:
- db.collection.aggregate( [ { $project: { myArray: [ "$x", "$y", "$someField" ] } } ] )
The operation returns the following document:
- { "_id" : ObjectId("55ad167f320c6be244eb3b95"), "myArray" : [ 1, 1, null ] }
See also
Aggregation with the Zip Code Data Set,Aggregation with User Preference Data