Reputation: 199
I have a data collection similar to:
{
"_id" : 1,
"name" : "Class 1",
"students" : [
{ "rollNo" : 10001, "name" : "Ram", "score" : 65 },
{ "rollNo" : 10002, "name" : "Shyam", "score" : 90 },
{ "rollNo" : 10003, "name" : "Mohan", "score" : 75 }
]
},
{
"_id" : 2,
"name" : "Class 2",
"students" : [
{ "rollNo" : 20001, "name" : "Krishna", "score" : 88 },
{ "rollNo" : 20002, "name" : "Sohan", "score" : 91 },
{ "rollNo" : 20003, "name" : "Radhika", "score" : 82 },
{ "rollNo" : 20004, "name" : "Komal", "score" : 55 }
]
},
{
"_id" : 3,
"name" : "Class 3",
"students" : [
{ "rollNo" : 30001, "name" : "Monika", "score" : 77 },
{ "rollNo" : 30002, "name" : "Rahul", "score" : 81 }
]
}
In this case I want to grab all students that have a score greater than or equal to 90. The expected output is:
{
"_id" : 1,
"name" : "Class 1",
"students" : [
{ "rollNo" : 10002, "name" : "Shyam", "score" : 90 }
]
},
{
"_id" : 2,
"name" : "Class 2",
"students" : [
{ "rollNo" : 20002, "name" : "Sohan", "score" : 91 },
]
},
I've tried the following, but it grabs all of Class 1 and Class 2
db.school.find({ $match : {'students.score': { $gte : 90 }}})
Upvotes: 0
Views: 37
Reputation: 364
I think this is what you need:
db.school.aggregate([
{
$project: {
students: {
$filter: {
input: "$students",
as: "student",
cond: { $gte: ["$$student.score", 90] }
}
},
name: 1,
_id: 1
}
},
{ $match: { students: { $exists: 1, $ne: [] } } }
])
But that does not seem elegant enough for me. There must be a better solution.
You can read about it here: https://docs.mongodb.com/manual/reference/operator/aggregation/filter/
Upvotes: 1