To achieve the desired result, utilizing the aggregation framework is necessary. This involves running an aggregation pipeline that incorporates a $group
operator pipeline stage. This stage aggregates the documents to generate the desired counts by using the accumulator operator $sum
.
In order to create independent count fields, a ternary operator such as $cond
is essential. This operator facilitates the evaluation of counts based on the value of the "reply" field. Based on a logical condition, the $cond
operator assigns a value of 1 or 0, translating boolean results into numerical values to be fed into the $sum
expression:
"$cond": [
{ "$eq": ["$reply", ">"] },
1, 0
]
When processing a document, if the "reply" field contains a ">", the $cond
operator assigns a value of 1 to $sum
. Otherwise, it sums up zero.
For the final step in the pipeline, utilize the $project
operator. This step allows for reshaping each document in the stream, including/excluding fields, renaming fields, injecting computed values, and more, similar to the SQL SELECT
statement.
The following pipeline executes the desired outcome:
Model.aggregate([
{
"$group": {
"_id": "$criterion",
">": {
"$sum": {
"$cond": [
{ "$eq": [ "$reply", ">" ] },
1, 0
]
}
},
"<": {
"$sum": {
"$cond": [
{ "$eq": [ "$reply", "<" ] },
1, 0
]
}
}
}
},
{
"$project": {
"_id": 0,
"criterion": "$_id",
"result.>": "$>",
"result.<": "$<"
}
}
]).exec(function(err, result) {
console.log(JSON.stringify(result, null, 4));
});
Sample Console Output
{
"criterion" : "story",
"result" : {
">" : 1,
"<" : 2
}
}
Note: This method assumes fixed values for the $reply
field. If the values are dynamic or unknown, this approach may not be flexible.
For a more efficient and flexible alternative that handles unknown count field values, consider using the following pipeline:
Model.aggregate([
{
"$group": {
"_id": {
"criterion": "$criterion",
"reply": "$reply"
},
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.criterion",
"result": {
"$push": {
"reply": "$_id.reply",
"count": "$count"
}
}
}
}
]).exec(function(err, result) {
console.log(JSON.stringify(result, null, 4));
});
Sample Console Output
{
"_id" : "story",
"result" : [
{
"reply" : "<",
"count" : 2
},
{
"reply" : ">",
"count" : 1
}
]
}