Get filtered elements from array of object in mongodb document based on flag in elements

Viewed 23

I have a one collection called User. Every user consists data like below document. I want to get an user with history data but history array should contains only active records in the array.

{
    "_id" : ObjectId("62f1df89fd621s2c419e5d47"),
    "name" : "Test User",
    "createDate" : ISODate("2022-08-25T04:43:33.949Z"),
    "history" : [ 
        {
            "departmentName" : "department1",
            "active" : false
        }, 
        {
            "departmentName" : "department2",
            "active" : true
        }, 
        {
            "departmentName" : "department3",
            "active" : false
        }
    ],
    "updateDate" : ISODate("2022-08-25T05:26:53.281Z")
}

This is the output I want:

{
    "_id" : ObjectId("62f1df89fd621s2c419e5d47"),
    "name" : "Test User",
    "createDate" : ISODate("2022-08-25T04:43:33.949Z"),
    "history" : [ 
        {
            "departmentName" : "department2",
            "active" : true
        }
    ],
    "updateDate" : ISODate("2022-08-25T05:26:53.281Z")
}

Tried with the below query but unable to get the expected result

db.getCollection('users')
.aggregate([{
    $match : {'name' : 'Test User','history.active' : true}
    }])
1 Answers

You just need to filter the histroy array - using $filter, like so:

db.collection.aggregate([
  {
    $match: {
      "name": "Test User",
      "history.active": true
    }
  },
  {
    $addFields: {
      history: {
        $filter: {
          input: "$history",
          cond: {
            $eq: [
              "$$this.active",
              true
            ]
          }
        }
      }
    }
  }
])

Mongo Playground

Related