Hello guys I’m writing a Message Application with Node.js and Mongoose. I keep datas in mongodb like that:
I want to list users who messaged before so I need to filter my ‘Messages’ collection but I can’t do what exactly I want. If he sent a message to a person I need to take persons name but, if he take a message from a person I need to take persons name however in first situation person name in reciever, in second situation person name in sender. I made a table for explain more easily. I have left table and I need 3 name like second table.(Need to eliminate one John’s name)
Sorry, if this problem asked before but I don’t know how can I search this problem.
I tried this but it take user name who logged in and duplicate some names.
Message.find({$or: [{sender: req.user.username}, {reciever: req.user.username}]})
2
Answers
This is a tricky one, but can be solved with a fairly simple aggregation pipeline.
Explanation
On our first stage of the pipeline, we will want to get all the messages sent or received by the user (in our case
David
), for that we will use a$match
stage:After we found all the messages from or to
David
, we can start collecting the people he talks to, for that we will use a$group
stage and use 2 operations that will help us to achieve this:receiver
or thesender
, depending which one of them isDavid
.The stage will look like this:
Combining these 2 stages together will give us the expected result, one document looking like this:
Final Solution
Sources
One option is to use an aggregation pipeline to create two sets and simply union them:
See how it works on the playground example