I have a data collection containing data in the following shape:
[ {_id: "1",
aa1: 45, aa2: 56,
bb1: 90, bb2: 78,
cc1: 34, cc2: 98 },
{_id: "2",
aa1: 76, aa2: 56,
bb1: 45, bb2: 67,
cc1: 75, cc2: 87 } ]
on this data I perform a MongoDB aggregation pipeline:
db.colleciton.aggregate([
{ $project: {
"_id": "$_id",
"aaa": { $avg: ["$aa1","$aa2"] },
"bbb": { $avg: ["$bb1","$bb2"] },
"ccc": { $avg: ["$cc1","$cc2"] }
}
},
{ $group: {
"_id": "AvgCalc",
"aaa": { $avg: "$aaa" },
"bbb": { $avg: "$bbb" },
"ccc": { $avg: "$ccc" }
}
}
])
that gives my result in the format:
[ {_id: "AvgCalc",
aaa: 67,
bbb: 55,
ccc: 90} ]
I would like to convert this in the aggregation to give my result as:
[ {field: "aaa", value: 67},
{field: "bbb", value: 55},
{field: "ccc", value: 90} ]
Is there a way to achieve this with aggregation? I would like to add this as a final stage in the pipeline. I tried adding a $project stage but with no success.
To use the $merge stage, it must be the last stage in the pipeline. New in version 4.2. Writes the resulting documents of the aggregation pipeline to a collection. To use the $out stage, it must be the last stage in the pipeline.
aggregate() method returns a cursor to the documents produced by the final stage of the aggregation pipeline operation, or if you include the explain option, the document that provides details on the processing of the aggregation operation.
With aggregate + $match, you get a big monolithic BSON containing all matching documents. With find, you get a cursor to all matching documents. Then you can get each document one by one.
We can group by single as well as multiple field from the collection, we can use $group operator in MongoDB to group fields from the collection and returns the new document as result. We are using $avg, $sum, $max, $min, $push, $last, $first and $addToSet operator with group by in MongoDB.
This pipeline should give you the desired result
db.getCollection('yourColl').aggregate([
{
$project: {
"_id": "$_id",
"aaa": { $avg: ["$aa1","$aa2"] },
"bbb": { $avg: ["$bb1","$bb2"] },
"ccc": { $avg: ["$cc1","$cc2"] }
}
},
{
$group: {
"_id": "AvgCalc",
"aaa": { $avg: "$aaa" },
"bbb": { $avg: "$bbb" },
"ccc": { $avg: "$ccc" }
}
},
{
$project: {
"items": [
{name: {$literal: "aaa"}, value: "$aaa"},
{name: {$literal: "bbb"}, value: "$bbb"},
{name: {$literal: "ccc"}, value: "$ccc"}
]
}
},
{
$unwind: {
path: "$items"
}
},
{
$project: {
_id: 0,
field: "$items.name",
value: "$items.value"
}
}
])
For your sample data the previous output was
/* 1 */
{
"_id" : "AvgCalc",
"aaa" : 58.25,
"bbb" : 70.0,
"ccc" : 73.5
}
and with the new pipeline the output is like this
/* 1 */
{
"field" : "aaa",
"value" : 58.25
}
/* 2 */
{
"field" : "bbb",
"value" : 70.0
}
/* 3 */
{
"field" : "ccc",
"value" : 73.5
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With