The $group stage in MongoDB is used for grouping documents based on a specified key(s) in aggregation. The $group stage takes one or more fields as input and returns a new set of documents that have been grouped based on those fields.
Related: Group by Multiple Fields in MongoDB
This is similar to the SQL GROUP BY clause where it is used to collect identical data into groups and perform aggregate functions on the grouped data. Group operation involves splitting the data, applying some functions, and finally aggregating the results.
In this article, we will discuss the $group stage using different examples. First, let's create a student collection and use this to explain the $group stage.
# Create Collection
db.student.insertMany([
{
_id: 1,
name: "Jimmy",
age: 24,
batch: 2022,
email: "jimmy@gmail.com",
marks: 75,
date: ISODate("2022-01-01T00:00:00Z")
},
{
_id: 2,
name: "Elena",
age: 20,
batch: 2021,
email: "elena@gmail.com",
marks: 80,
date: ISODate("2021-02-02T00:00:00Z")
},
{
_id: 3,
name: "Caroline",
age: 25,
batch: 2020,
email: "caroline@gmail.com",
marks: 95,
date: ISODate("2020-06-01T00:00:00Z")
},
{
_id: 4,
name: "Elan",
age: 23,
batch: 2023,
email: "elan@gmail.com",
marks: 60,
date: ISODate("2023-01-23T00:00:00Z")
}
]
)
)
<a id="h-1-syntax-of-group-stage-in-mongodb"></a>
1. Syntax of $group stage in MongoDB
The following is the syntax of the $group stage in MongoDB.
# Syntax of $group
{
$group:
{
_id: group_key
field: { accumulator_operator : expression },....
}
}
)
Here,
$groupis a stage that is used to group documents by field.group_keyis the field we want to group byaccumulator_operatoris one of the accumulator operators likemin,max,counte.t.c, andexpressionis the expression to apply the accumulator operator.
<a id="h-2-using-count-to-get-the-number-of-documents-for-each-group-in-mongodb"></a>
2. Using count to get the number of documents for each group in MongoDB
The $count operator is used to get the number the documents in each group from the MongoDB collection. In the below example, the $count accumulator operator is used to get the number of documents in each group and the $group operator groups the documents by the name field. Since we have passed an empty object {} as an argument, the $count will consider all documents in each group.
# Usage of $count operator
db.student.aggregate( [
{
$group: {
_id: "$name",
countNumberOfDocuments: {
$count: {}
}
}
}
] )
)
This example yields the below output.
<a id="h-3-group-by-a-field-and-add-a-set-of-unique-value"></a>
3. Group by a field and add a set of unique value
Sometimes, we may need to group the fields and adds unique values to an array in a group. The $addToSet accumulator operator is used to insert the unique set of values. Here, our query groups the documents based on the email field. Then, for each unique email address, the $addToSet operator creates an array of all the unique batch values associated with that email.
# Usage of $addToSet accumulator operator
db.student.aggregate([
{ $group: {
_id: "$email",
Batch: { $addToSet: "$batch" }
}}
])
)
The following output represents the set of documents with each document with a unique email address and containing an array of all the unique batch values associated with that email.
<a id="h-4-get-group-by-and-average-of-the-in-mongodb"></a>
4. Get Group by and average of the in MongoDB
The $avg accumulator operator in the $group calculates the average numeric values in a group in MongoDB. In the below example, we have grouped the age field. After that, the $avg operator is used within the $group stage to calculate the average value of the marks field for each group.
# Usage of $avg accumulator operator
db.student.aggregate([
{ $group: {
_id: "$age",
avg_sales: { $avg: "$marks" }
}}
])
)
The following output shows the average marks for each group.
<a id="h-5-group-by-a-field-and-get-the-maximum-value"></a>
5. Group by a field and get the maximum value
The $max accumulator operator returns the maximum value encountered in a group. Here, after grouping by the email field, we have used the $max operator in the $group stage to find the maximum value of the age field for each group.
# Usage of $max accumulator operator
db.student.aggregate([
{ $group: {
_id: "$email",
max_age: { $max: "$age" }
}}
])
)
The following output displayed the value of the maximum age for each of the groups.
<a id="h-6-group-by-a-field-and-get-the-minimum-value"></a>
6. Group by a field and get the minimum value
Similar to the above example, we have the $min accumulator to get the minimum value encountered in a group. Here, we have used the $min operator with $group stage to get the minimum marks for each of the group by name field documents.
#Usage of $min accumulator
db.student.aggregate([
{ $group: {
_id: "$name",
min_marks: { $min: "$marks" }
}}
])
)
This example yields the following output.
<a id="h-7-group-by-a-field-and-get-the-first-value-in-a-group"></a>
7. Group by a field and get the first value in a group
The $first operator is also an accumulator operator of the $group stage that returns the first value encountered in a group, here is an MongoDB example using $first.
# Usage of $first operator
db.student.aggregate(
[
{ $sort: { name: 1, date: 1 } },
{
$group:
{
_id: "$email",
firstAdmissionDate: { $first: "$date" }
}
}
]
)
Here, we have first used the $sort operator to sort the documents by their name field in ascending order, and then by their date field in ascending order. It then groups the sorted documents by their email field. After that, we use the $first operator in the $group stage which finds the first value of the date field for each group.
If you want to know about grouping values by multiple fields in MongoDB, you can visit the following link.
<a id="h-8-conclusion"></a>
8. Conclusion
In conclusion, the $group stage in MongoDB is very handful to perform complex data manipulations and analysis like aggregations. All the above examples of the $group stage are easy to implement for grouping the fields and getting the aggregate results.
More details about this topic can be found here.
