Reputation: 6491
I have the following query, it is supposed to pull out the most recent message sent from all users to a single user:
await Conversation.aggregate(
[
// Matching pipeline, similar to find
{
$match: {
recipient: mongoose.Types.ObjectId(id)
}
},
// Sorting pipeline
{
$sort: {
date: -1
}
},
// Grouping pipeline
{
$group: {
_id: "$_id",
sender: {
$first: "$sender"
},
text: {
$first: "$text"
},
date: {
$first: "$date"
},
unread: {
$first: "$unread"
}
}
},
{
$lookup: {
from: "users",
localField: "sender",
foreignField: "_id",
as: "sender"
}
},
{ $unwind: { path: "$sender" } },
// Project pipeline, similar to select
{
$project: {
sender: 1,
_id: 1,
text: 1,
date: 1,
unread: 1
}
}
],
function(err, messages) {
if (err) {
console.log("err with agg query", err);
} else {
console.log("latestMessages", messages);
}
}
);
The problem is that it returns more than one record. It returns:
[
{
_id: 5d9b51eed6606f12f5434d46,
sender: {
_id: 5d9b5142d6606f12f5434d41,
email: null,
numberOfPosts: 0,
date: 2019-10-07T14:52:50.467Z,
__v: 0
},
text: 'Ayyy',
date: 2019-10-07T14:55:42.141Z,
unread: false
},
{
_id: 5d9b5178d6606f12f5434d43,
sender: {
_id: 5d9b5142d6606f12f5434d41,
email: null,
numberOfPosts: 0,
date: 2019-10-07T14:52:50.467Z,
__v: 0
},
text: 'hey!',
date: 2019-10-07T14:53:44.073Z,
unread: false
}
]
When it should be returning just the first element where sender is 5d9b5142d6606f12f5434d41
, the first, latest object.
What am I doing wrong here?
Upvotes: 0
Views: 235
Reputation: 116
Change the qroup pipeline just like
You need to group by on sender not on unique _id
{
$group: {
_id: "$sender",
sender: {
$first: "$sender"
},
messageId: {
$first: "$_id"
},
text: {
$first: "$text"
},
date: {
$first: "$date"
},
unread: {
$first: "$unread"
}
}
}
And change in $project
$project: {
sender: 1,
_id: "$messageId",
text: 1,
date: 1,
unread: 1
}
Upvotes: 1