Overview$project can be used to reshape a document stream by renaming fields, adding fields, or removing fields. SpecificationFor the examples that follow, imagine an article collection made up of documents that look like this: {
title : "this is my title" ,
author : "bob" ,
posted : new Date() ,
pageViews : 5 ,
tags : [ "fun" , "good" , "fun" ] ,
comments : [
{ author :"joe" , text : "this is cool" } ,
{ author :"sam" , text : "this is bad" }
],
other : { foo : 5 }
});
Inclusion and Exclusion$project can be used to include or exclude fields using the same syntax as the query field selection syntax (see Field Selection). In this mode, a field path specification is given a value of 1 or 0 to include or exclude that field. If the first field to use this mode specifies a 1, then the projection will only include this and other fields explicitly included in this way, except for _id, which is always included by default. However, even in this inclusionary mode, _id may be excluded with _id:0; no other fields may be excluded in this mode. An inclusion will not create a field if it does not already exist in a document. If the first field to use this mode specifies a 0, then the projection will include all fields except those which are explicitly excluded like this one. When fields are excluded in this way, no fields may be explicitly included using :1. Dotted field paths may be used to include or exclude fields in nested documents. This syntax requires that the field paths be enclosed in quotes to conform to JSON syntax. Here are some projection specifications for a collection of articles as exemplified above. Field inclusion: db.runCommand(
{ aggregate : "article", pipeline : [
{ $project : {
title : 1 , /* include this field, if it exists */
author : 1 , /* include this field, if it exists */
"comments.author" : 1 /* include the "author" field in each document in "comments", if it exists */
}}
]});
In inclusion mode, _id is always included by default. As a special case, inclusions may explicitly exclude _id. db.article.aggregate(
{ $project : {
_id : 0 , /* exclude _id */
title : 1 , /* include this field, if it exists */
author : 1 /* include this field, if it exists */
}}
);
In exclusionary mode, all fields except those that are excluded will pass through: db.article.aggregate(
{ $project : {
comments : 0 ,/* exclude this field */
other : 0 /* exclude this field */
}}
);
Computed FieldsProjections may be used to add computed fields to the document stream passing through the pipeline. A computed field may use any of the expressions from the Aggregation Framework - Expression Reference. Here is a simple example that shows how to add a value to a field, creating a new computed field: db.article.aggregate(
{ $project : {
title : 1,
doctoredPageViews : { $add:["$pageViews", 10] }
}}
);
Note the expression must be enclosed in braces to make it look like an object for the sake of conforming to JavaScript syntax. Renaming FieldsField references are a direct expression without an operator, and can be used without surrounding braces to rename existing fields. Field references here (and in any expression) can be dotted paths. Here is a simple example: db.article.aggregate(
{ $project : {
title : 1 ,
page_views : "$pageViews" , /* rename this field */
florble : "$other.foo" /* expose this nested field as if it were top-level */
}}
);
Document-Valued FieldsAnother form of computed field is a newly created sub-document. Field renaming and expressions can be used to populate a new sub-document that only exists in the result set. Here is an example: db.article.aggregate(
{ $project : {
title : 1 ,
stats : { /* the value of this new field is a sub-document */
pv : "$pageViews", /* rename this from the top-level */
foo : "$other.foo", /* a dotted field path expression */
dpv : { $add:["$pageViews", 10] } /* a regular computed expression */
}
}}
);
NotesField OrderingThe BSON specification specifies that field order matters, and is to be preserved. A projection will honor that, and fields will be output in the same order as they are input, regardless of the order of any inclusion or exclusion specifications. When new computed fields are added via a projection, these always follow all fields from the original source, and will appear in the order they appear in the projection specification. |

PLEASE POST QUESTIONS IN THE USER GROUPS FORUM. Post non-question comments and helpful hints here.
blog comments powered by Disqus