Bohr Hew
Bohr Hew

Reputation: 199

MongoDB: Filtering out elements from nested arrays

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

Answers (1)

Tim Nimets
Tim Nimets

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

Related Questions