0

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 }}})

1 Answer 1

1

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/

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks, I was hoping there would be a simpler solution, but the query makes sense to me. I removed name/id from the projection and exists.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.