Reputation: 1405
I have a posts collection. Each post has a thread as part of the document.
Here is some pseudo code for a post document:
{
'_id':...,
'date': date,
'thread': 'thread name is a string',
'message': 'whatever the person wrote',
}
I want to receive the 5 most recent posts, but none of the 5 returned can be from the same thread. I hope that explain it good enough. How would I do this? Keeping it reactive preferred, but not completely necessary.
Update: Just wanted to thank Tom for the code and pointing out rawCollection, very useful.
Upvotes: 0
Views: 242
Reputation: 143
Just as a disclaimer, I took this as a bit of a learning exercise so whilst it should get you the result you're after I cannot comment as to how efficient it is!
MongoDB has a distinct() function that returns unique results but you cannot then sort/limit by what it returns. Not much use.
Instead, I think you'll have to use MongoDB's aggregate() function.
You cannot natively access aggregate() via Meteor, hence MurWade's suggestion of using a package. However, if you're using Meteor 1.0.4 or above you can make use of rawCollection() to access the aggregate() function.
rawCollection() can only be called server-side, so my example below is a Meteor method that returns the _ids of the five most recent, distinct, posts.
if (Meteor.isServer) {
Meteor.methods({
recentDistinctPostIds: function() {
var rawPosts = Posts.rawCollection();
var aggregateQuery = Meteor.wrapAsync(rawPosts.aggregate, rawPosts);
return aggregateQuery([{
$group: {
_id: '$thread',
date: {$max: '$date'},
postId: {$first: '$_id'}
}},
{$sort: {date: -1}},
{$limit: 5},
]);
}
});
}
You would then call the method client side with a callback, e.g.
Meteor.call('recentDistinctPostIds', function(err, result) {
console.log(result)
});
I hope that makes sense but just shout if it doesn't work as intended!
Upvotes: 1