In my project, I have defined a model called MostRecentMessage
, which looks like this:
const MostRecentMessage = new Schema({
to: {
type: mongoose.Schema.Types.ObjectId,
ref: "user"
},
from: {
type: mongoose.Schema.Types.ObjectId,
ref: "user"
},
conversation: {
type: mongoose.Schema.Types.ObjectId,
ref: "conversation"
},
date: {
type: Date,
default: Date.now
}
});
Whenever User A sends a message to User B, a document is created if it doesn't exist. This document gets updated each time User A sends a new message to User B with the latest conversation
and date
. Here's an example of how a document looks like:
_id: ObjectId(5dc46521cf670a0017d2434d)
to: ObjectId(5dc464ce2fd75700178c1ad4) // User B
from: ObjectId(5dc464fc2fd75700178c1ad5) // User A
conversation: ObjectId(5dc465c6cf670a0017d24363)
date: 2019-11-07T18:40:33.242+00:00
__v: 0
The purpose of this setup is to keep track of all recent messages sent to specific users.
If User B replies to User A, a similar document is created as shown above, and it also gets updated when User B sends more messages to User A.
Now, let's take a look at my aggregation query, but there seems to be an issue where it only returns one conversation even if multiple users are talking to User A.
const { id } = req.user;
try {
await MostRecentMessages.aggregate(
[
{
$match: {
$or: [
{ from: mongoose.Types.ObjectId(id) },
{ to: mongoose.Types.ObjectId(id) }
]
}
},
{ $project: { _id: 1, from: 1, to: 1, conversation: 1, date: 1 } },
{ $sort: { date: -1 } },
{
$group: {
_id: null,
from: { $first: "$from" },
to: { $first: "$to" },
date: { $first: "$date" },
conversation: { $first: "$conversation" }
}
},
{
$lookup: {
from: "conversations",
localField: "conversation",
foreignField: "_id",
as: "conversation"
}
},
{ $unwind: { path: "$conversation" } },
{
$lookup: {
from: "users",
localField: "to",
foreignField: "_id",
as: "to"
}
},
{ $unwind: { path: "$to" } },
{
$lookup: {
from: "users",
localField: "from",
foreignField: "_id",
as: "from"
}
},
{ $unwind: { path: "$from" } }
],
function(err, docs) {
if (err) {
console.log(err);
} else {
return res.json(docs);
}
}
);
} catch (err) {
console.log(err);
return res.status(500).send("Server error");
}
However, the current implementation of the code displays only the last message exchanged between User A and User B. How can we modify the query to show all messages for both users?
Any thoughts on what might be going wrong here or suggestions for improvement would be much appreciated!