Ameet Pradhan
Ameet Pradhan

Reputation: 17

mongodb aggregate on array of objects

I'm trying to group my participants array in to such a way that for a single participant I should get all the meeting under that participant in an array.

[
    {
        "_id": "5fc73e7131e6a20f6c492178",
        "participants": [
            {
                "_id": "5fc74bc5e7c54d0ea8f133ca",
                "rsvp": "Yes",
                "name": "Participant 1",
                "email": "[email protected]"
            },
            {
                "_id": "5fc74e1254b8d337b4ae36d2",
                "rsvp": "Not Answered",
                "name": "Participant 2",
                "email": "[email protected]"
            }
        ],
        "title": "Meeting 1",
        "startTime": "2020-11-01T18:30:00.000Z",
        "endTime": "2020-11-03T18:30:00.000Z"
    },
    {
        "_id": "5fc73f1cdfc45d3ca0c84654",
        "participants": [
            {
                "_id": "5fc74bc5e7c54d0ea8f133ca",
                "rsvp": "Yes",
                "name": "Participant 2",
                "email": "[email protected]"
            }
        ],
        "title": "Meeting 2",
        "startTime": "2020-11-01T18:30:00.000Z",
        "endTime": "2020-11-03T18:30:00.000Z"
    }
]

my expected result should be like

[{
"participant": {
                "_id": "5fc74bc5e7c54d0ea8f133ca",
                "rsvp": "Yes",
                "name": "Participant 1",
                "email": "[email protected]"
},
meetings: [{meeting1, meeting2, ...and so on}]
},
{
"participant": {
                "_id": "5fc74bc5e7c54d0ea8f133ca",
                "rsvp": "Yes",
                "name": "Participant 2",
                "email": "[email protected]"
},
meetings: [{meeting2, meeting3, ...and so on}]
}
]

I'm kinda stuck for hours to figure it out. I tried the approach by using $group and $unwind but I was getting participants as an array consisting of a single participant(object). and on that I was unable to run $match to match according to the participant's email because participants field was an array. I tried this

            const docs = await Meeting.aggregate([
                { $unwind: '$participants' },
                {
                    $lookup: {
                        from: 'participants',
                        localField: 'participants',
                        foreignField: '_id',
                        as: 'participants'
                    }
                },
                { $match },
                { $group: { _id: "$participants", meetings: { $push: "$$ROOT" } } },
            ]);

but this is not matching the expected result which I want it to be.

Upvotes: 0

Views: 372

Answers (1)

varman
varman

Reputation: 8894

You can unwind to deconstruct the array and use group to get your desired output

db.collection.aggregate([
  {
    "$unwind": "$participants"
  },
  {
    $group: {
      _id: "$participants._id",
      participants: {
        $first: "$participants"
      },
      meetings: {
        "$addToSet": "$title"
      }
    }
  }
])

Working Mongo playground

Upvotes: 1

Related Questions