mongodb aggregation framework walk through by examples

Mongodb aggregation framework takes an array of json documents. Each document represents a stage which starts with a stage operator such as $match, $project, $group, $sort, $limit, etc. The stage operator is the key of a value or a json document. Each stage is processed in sequence, the results from the 1st stage is passed to the 2nd stage, the 2nd stage passes its results to the third stage. It goes on util the last stage (last document in the array) is processed. The results from the last stage will be the final query results.
Assum there is a collection named people with documents like these and the task is to find the number of programmers in various interests, and sort in descending order.

{"name":"Emily", "career":"Programmer", "interests":["dance", "movies"]}
{"name":"Carol", "career":"Lawyer", "interests":["reading", "sports"]}
{"name":"Amy", "career":"Writer", "interests":["writing", "reading"]}
{"name":"Fiona", "career":"Programmer", "interests":["coding", "movies"]}
{"name":"Denny", "career":"Programmer", "interests":["coding", "traveling"]}
{"name":"Gina", "career":"Lawyer", "interests":["reading", "movies"]}
{"name":"Ben", "career":"Programmer", "interests":["coding", "traveling"]}

First stage, using the stage operator $match to find all programmers.

db.people.aggregate([
{
	$match: {"career": "Programmer"}
}
]);

//The results
{ "_id" : ObjectId("5533d3268de00dc152932854"), "name" : "Emily", "career" : "Programmer", "interests" : [ "dance", "movies" ] }
{ "_id" : ObjectId("5533d3268de00dc152932856"), "name" : "Fiona", "career" : "Programmer", "interests" : [ "coding", "movies" ] }
{ "_id" : ObjectId("5533d3268de00dc152932857"), "name" : "Denny", "career" : "Programmer", "interests" : [ "coding", "traveling" ] }
{ "_id" : ObjectId("5533d3268de00dc152932859"), "name" : "Ben", "career" : "Programmer", "interests" : [ "coding", "traveling" ] }

The second stage gets the results from the first stage, and then uses the stage operator $unwind to list interest individually for each programmer. The dollar sign is required to specify the field to unwind, so there is a dollar sign in front of interests.

db.people.aggregate([
{
	$match: {"career": "Programmer"},
},
{$unwind: "$interests"}
]);

//results
{ "_id" : ObjectId("5533d3268de00dc152932854"), "name" : "Emily", "career" : "Programmer", "interests" : "dance" }
{ "_id" : ObjectId("5533d3268de00dc152932854"), "name" : "Emily", "career" : "Programmer", "interests" : "movies" }
{ "_id" : ObjectId("5533d3268de00dc152932856"), "name" : "Fiona", "career" : "Programmer", "interests" : "coding" }
{ "_id" : ObjectId("5533d3268de00dc152932856"), "name" : "Fiona", "career" : "Programmer", "interests" : "movies" }
{ "_id" : ObjectId("5533d3268de00dc152932857"), "name" : "Denny", "career" : "Programmer", "interests" : "coding" }
{ "_id" : ObjectId("5533d3268de00dc152932857"), "name" : "Denny", "career" : "Programmer", "interests" : "traveling" }
{ "_id" : ObjectId("5533d3268de00dc152932859"), "name" : "Ben", "career" : "Programmer", "interests" : "coding" }
{ "_id" : ObjectId("5533d3268de00dc152932859"), "name" : "Ben", "career" : "Programmer", "interests" : "traveling" }

The third stage gets the results from the second stage and uses the stage operator $group for finding the number of programmers in various interests.

db.people.aggregate([
{
	$match: {"career": "Programmer"},
},
{	
	$unwind: "$interests"
},
{
	$group: {"_id":"$interests", "count": {$sum:1}}
}
]);

//results
{ "_id" : "traveling", "count" : 2 }
{ "_id" : "coding", "count" : 3 }
{ "_id" : "movies", "count" : 2 }
{ "_id" : "dance", "count" : 1 }

The fourth stage gets the results from the third stage and then $sorts the results by count in descending order.

db.people.aggregate([
{
	$match: {"career": "Programmer"},
},
{	
	$unwind: "$interests"
},
{
	$group: {"_id":"$interests", "count": {$sum:1}}
},
{
	$sort: {"count":-1}
}
]);

//results
{ "_id" : "coding", "count" : 3 }
{ "_id" : "traveling", "count" : 2 }
{ "_id" : "movies", "count" : 2 }
{ "_id" : "dance", "count" : 1 }

Search within Codexpedia

Custom Search

Search the entire web

Custom Search