Reputation: 21
I have this type of documents:
collection:People
{name:"George", grade:5, school:"MathHighSchool"}
and many more examples.
I need a query that finds all people who:
study in the MathHighSchool (so we have db.people.aggregate({$match:{school:"MathHighSchool"}},....
)
and then group them by their grades, as it shows the number of people with grade <3 number of people with grade between 3 and 5 and number of people with grade > 5. Any ideas?
Upvotes: 0
Views: 1387
Reputation: 1
We can also achieve this solution using switch case in mongo and if condition also, here is a little approach to achieve the solution.
Query:
db.people.aggregate([
{$match:{"school":"MathHighSchool"}},
{$project:{"school":1,"div": { $switch:
{
branches: [
{
case: { $lte : ["$grade", 3 ] },
then: "less than or equal to 3"
},
{
case: { $and : [ { $gt : ["$grade", 3 ] },
{ $lt : [ "$grade", 5 ] } ] },
then: "between 3 and 5"
},
{
case: { $gte : [ "$grade", 5] },
then: "greater than or equal to 5"
}],
}}}},
{$group:{"_id":"$div","count":{$sum:1}}}
]);
Result:
{
"_id" : "between 3 and 5",
"count" : 1.0
}
{
"_id" : "less than or equal to 3",
"count" : 2.0
}
{
"_id" : "greater than or equal to 5",
"count" : 3.0
}
Please Visit here for more detail https://beingcodeexpert.blogspot.com/2021/02/switch-conditional-operator-in-mongodb.html
Upvotes: 0
Reputation: 65403
In order to conditionally sum matches in your $group
pipeline step, you need to use the $cond
operator.
Test data set up:
db.people.insert([
{name:"George", grade:5, school:"MathHighSchool"},
{name:"John", grade:4, school:"MathHighSchool"},
{name:"Paul", grade:3, school:"MathHighSchool"},
{name:"Ringo", grade:5, school:"MathHighSchool"},
{name:"Johnny", grade:2, school:"MathHighSchool"},
{name:"Joshua", grade:7, school:"MathHighSchool"},
])
Assuming you just want the counts, here is an example aggregation (tested with MongoDB 2.4.8):
db.people.aggregate(
{ $match: {
school : 'MathHighSchool'
}},
{ $group: {
_id: "$school",
// Add up matches less than grade 3
low: { $sum: { $cond: [ {$lt: ["$grade", 3] }, 1, 0] }},
// Add up matches between 3 and 5 (inclusive)
medium: { $sum: { $cond:[
{ $and: [ {$gte: ["$grade", 3]}, {$lte: ["$grade", 5]} ] }, 1, 0]
}},
// Add up matches greater than grade 5
high: { $sum: { $cond: [ {$gt: ["$grade", 5] }, 1, 0] }},
}}
)
Result:
{
"result" : [
{
"_id" : "MathHighSchool",
"low" : 1,
"medium" : 4,
"high" : 1
}
],
"ok" : 1
}
Upvotes: 4