2

I try to learn aggregation concept in MongoDB. I create an object like this for training.

"_id": "601c4bb56e018211b02abbf8",   
"isDeleted": false,
"name": "TeacherName1",
"class": "7",
"students": [
     { "_id": "601c4bb56e018211b02abbf9", isDeleted:true,  "name": "student-1", "studentGroup": "A",   "avgResult": 36},
     { "_id": "601c4bb56e018211b02abbfa", isDeleted:false, "name": "student-2", "studentGroup": "A",   "avgResult": 55},
     { "_id": "601c4bb56e018211b02abbfb", isDeleted:false, "name": "student-3", "studentGroup": "B",   "avgResult": 44.66},
     { "_id": "601c4bb56e018211b02abbfc", isDeleted:false, "name": "student-4", "studentGroup": "C",   "avgResult": 83.66},
     { "_id": "601c4bb56e018211b02abbfd", isDeleted:true,  "name": "student-5", "studentGroup": "B",   "avgResult": 37},
     { "_id": "601c4bb56e018211b02abbfe", isDeleted:true,  "name": "student-6", "studentGroup": "C",   "avgResult": 39.66},
]

I want to get teacher information and deleted students (isDeleted=true). So I try to get this result.

    "_id": "601c4bb56e018211b02abbf8",   
    "isDeleted": false,
    "name": "TeacherName1",
    "class": "7",
    "students": [
         { "_id": "601c4bb56e018211b02abbf9", isDeleted:true,  ...},
         { "_id": "601c4bb56e018211b02abbfd", isDeleted:true, ...},
         { "_id": "601c4bb56e018211b02abbfe", isDeleted:true,  ...},
    ]

I get result with use $unwind and $filter. But can I get this result with only $elemMatch?

If I use this query

 this.aggregate([
    {
      $match: {
        _id: mongoose.Types.ObjectId("601c4bb56e018211b02abbf8"),
        isDeleted: false,
        "students.isDeleted":true
      },
    },
  ]);

It returns all object.

If I try this

this.aggregate([
    {
      $match: {
        _id: mongoose.Types.ObjectId("601c4bb56e018211b02abbf8"),
        isDeleted: false,
        students:{
            $elemMatch:{
                isDeleted:true
            }
        }
      },
    },
  ]);

It returns all object.

1 Answer 1

2

$match will just give you the whole doc should you match however you may use $project with $filter using another stage

given

db.dummy.insert({studs:[{isDeleted:true, name:'a'},{isDeleted: true, name:'b'},{name:'c'}]})
db.dummy.insert({studs:[{name:'c'}]})
> match = {$match:{studs:{$elemMatch: {isDeleted:true}}}}
> project = {$project: { deletedStuds: {$filter:{input: '$studs', as:'stud', cond:{ $eq: ['$$stud.isDeleted', true]} } } }}
{
  "$project" : {
    "deletedStuds" : {
      "$filter" : {
        "input" : "$studs",
        "as" : "stud",
        "cond" : {
          "$eq" : [
            "$$stud.isDeleted",
            true
          ]
        }
      }
    }
  }
}

> db.dummy.aggregate(match, project)
{ "_id" : ObjectId("6020351eb965951ac8a1eb62"), "deletedStuds" : [ { "isDeleted" : true, "name" : "a" }, { "isDeleted" : true, "name" : "b" } ] }

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

Comments

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.