Reputation: 4987
I'm kind of a newbie when it comes to NoSQL and Mongoose. I've been searching a bit but couldn't really find what i'm looking for (it makes it even harder that I don't really know the answer).
Basically, I have a list of records that are being added by users. These records contain some data, and I would like to have a list of the latest inserted message of every user.
In SQL I would write;
SELECT * FROM records ORDER BY inserted_date GROUP BY user_id;
This would return a set like so;
[
{user: 2, insert_date: 2015-08-12T15:15:00, message: "Hi"},
{user: 3, insert_date: 2015-08-12T15:12:00, message: "Also hi"},
{user: 5, insert_date: 2015-08-12T15:14:00, message: "Not hi"}
]
I have been looking around, found some answers but those didn't seem to work.
I've tried;
https://stackoverflow.com/a/7570091/1493455
And some other aggregate thingie like so;
Record.aggregate(
{},
{
$group: {
_id: '$user_id',
inserted: { $last: "$inserted" },
message: { $last: "$message" }
}
},
function(err, messages) {
console.log(err, messages);
}
);
which i've copied from another answer - but I don't really understand what its doing and what its even supposed to do.
I could ofcourse use a sort and limit query for every user, but this seems very inefficient.
I'd be pleased if someone can point me in the right direction :)
Upvotes: 0
Views: 1223
Reputation: 4987
Yep, duplicate of: Mongoose - find last message from each user
I ended up fixing my code with;
Record.aggregate(
[
// Matching pipeline, similar to find
{
"$match": {}
},
// Sorting pipeline
{
"$sort": {
"inserted": -1
}
},
// Grouping pipeline
{
"$group": {
"_id": "$user_id",
"message": {
"$first": "$message"
},
"inserted": {
"$first": "$inserted"
}
}
},
// Project pipeline, similar to select
{
"$project": {
"_id": 0,
"user_id": "$_id",
"message": 1,
"inserted": 1
}
}
],
function(err, messages) {
console.log(err, messages);
}
);
And updating to the latest mongodb (3.4) instead of the old (2.x) I was running (this gives errors because the aggregate is not supported yet).
Upvotes: 1