GET not returning sent message. Only inbox items GET not returning sent message. Only inbox items mongoose mongoose

GET not returning sent message. Only inbox items


You can use below aggregation to make sure that there will be only one document returned for every (recipient, sender) pair:

db.Messages.aggregate([    {        $addFields: { conversants: [ "$recipientId", "$creator" ] }    },    {        $match: { conversants: req.query.recipientId }    },    {        $addFields: { conversant: { $arrayElemAt: [ { $filter: { input: "$conversants", cond: { $ne: [ "$$this", "5df0014e25ee451beccf588a" ] } }  } , 0 ] } }    },    {        $sort: { creationDate: 1 }    },    {        $group: {            _id: "$conversant",            message: { $first: "$message" },            recipientId: { $first: "$recipientId" },            creator: { $first: "$creator" },            messageTrackingId: { $first: "$messageTrackingId" },            creationDate: { $first: "$creationDate" }        }    },            {        $lookup: {            from: "users",            let: { creator: "$creator" },            pipeline: [                { $match: { $expr: { $eq: [ "$_id", "$$creator" ] } } },                { $project: { creatorName: 1 } }            ],            as: "creatorName"        }    },    {        $addFields: { creatorName: { $arrayElemAt: [ "$creatorName", 0 ] } }    }])

The idea here is that you create additional field which represents two ids: creator and recipient. This will allow you to do two things: filter using recipientId (who may also be the sender) - step two, and select conversant value which is always the second person - no matter if a person specified in your request sent or received a message in that conversation. Then you can $group on that field to make sure that you'll get only single message in every "conversation". Instead of using $addToSet with $arrayElemAt you can just run $first. Relatively heavy $lookup can also be run as a last step since you need to get that data once per "conversant".

EDIT: first three stages can be replaced with below stages - that should significantly improve performance since the filtering will be applied as soon as possible:

{    $match: {        $or: [ { recipientId: req.query.recipientId  }, { creator: req.query.recipientId  } ]    }},{    $addFields: {         conversant: {             $cond: [ { $ne: [ "$recipientId", req.query.recipientId  ] }, "$recipientId", "$creator" ]         }     }},