Hi! How can I get the value of the exam score only, and not the whole document

{
_id: ObjectId(“50b59cd75bed76f46522c35a”),
student_id: 1,
class_id: 22,
scores: [
{ type: ‘exam’, score: 47.38775906993299 },
{ type: ‘quiz’, score: 9.963742963372834 },
{ type: ‘homework’, score: 22.17993073237026 },
{ type: ‘homework’, score: 33.7647119689925 },
{ type: ‘homework’, score: 18.29543263797219 }
]
}

Can you elaborate the requirements in more details?

What would be your input, and what would be your expected output?

@NeNaD, Im trying to find the exam score associated with the student_id = 1 and class_id = 22.

with the input bellow, i get the whole document:

db.grades.find( {student_id:1, class_id: 22, “scores.type”: “exam”} );

I hope there is a way to get this output:

{ type: ‘exam’, score: 47.38775906993299 }

You can do it like this:

  • $match - to filter the document you want.
  • $filter - to find the item in the scores array that you want.
  • $first - to take the first element from the array returned after the $filter.
  • $project - to specify what fields you want to be returned.
db.collection.aggregate([
  {
    "$match": {
      student_id: 1,
      class_id: 22,
      "scores.type": "exam"
    }
  },
  {
    "$set": {
      "data": {
        "$first": {
          "$filter": {
            "input": "$scores",
            "cond": {
              "$eq": [
                "$$this.type",
                "exam"
              ]
            }
          }
        }
      }
    }
  },
  {
    "$project": {
      "_id": 0,
      "score": "$data.score",
      "type": "$data.type"
    }
  }
])

Working example

2 Likes

I appreciate your help @NeNaD
Have a nice weekend!

1 Like

If you are only interested in the first element of the array that matches your query you could simply use

something like

db.grades.find( {student_id:1, class_id: 22, "scores.type": "exam"} ,{ "scores.$" : 1 })
3 Likes

This is fantastic! Thank you for your response and solution :+1:

2 Likes

This topic was automatically closed 5 days after the last reply. New replies are no longer allowed.