How do I properly aggregate results in a view using node.js & mongoose from mongodb. My programmer colleague came up with the following route to aggregate event and blog posts in one list/view of content sorted by day (if both "published" and "promoted" equal 1). The trouble with this is that the list of aggregate results is really just split into two (first events display, then blogs display) when they should render in a truly mixed fashion sorted by date. I would use a join or groupby in mysql but how would I do this type of aggregation in a node.js app with mongodb? Ps, we're using express and mongoose in case that helps.
Update: We've already defined the schema for the two (events and blogs), and there are thousands of records already stored. So the question now is, can we do this client side or do we have to create an index (another collection)? I'm reading up on mongodb's aggregation framework and map reduce as well but I'm not sure if either of those can help me at this point.
app.get('/promoted/content/:page?', userSession, function(req, res, next) {
var today = todayTimestamp();
var limit = 10;
if(req.params.page) {
var skip = req.params.page * limit;
} else {
var skip = 0;
}
async.parallel({
blogs: function(callback){
app.Blog.find()
.where('status').equals(1)
.where('promote').equals(1)
.sort('sticky', -1)
.sort('created', -1)
.populate('userId')
.exec(function(err, blogs) {
if (err) {
console.log(err);
} else {
callback(null, blogs);
}
});
},
events: function(callback){
app.Event.find()
.where('status').equals(1)
.where('promote').equals(1)
.sort('sticky', -1)
.sort('created', -1)
.populate('userId')
.exec(function(err, events) {
if (err) {
console.log(err);
} else {
callback(null, events);
}
});
}
},
// callback function to render page and pass in all data
function(err, results){
//add type field to results for logic in mixed output
for(i = 0; i < results.blogs.length; i++) {
results.blogs[i].type = 'blog';
}
for(i = 0; i < results.events.length; i++) {
results.events[i].type = 'event';
}
//combine results from blogs and events and sort the results
var promoted = results.events.concat(results.blogs);
var outputted = false;
promoted.sort(function( a, b )
{
// Sort by key of modification date in each array
if ( a['changed'] == b['changed'] ) return 0;
return a['changed'] < b['changed'] ? -1 : -1;
});
//create a subset
var subset = new Array();
for(var i = skip; i < (limit + skip); i++) {
subset.push(promoted[i]);
}
//check mobile
if(isMobile(req)) {
res.render('mobile/fragments/block_posts', { posts: subset, user: req.session.user, message: req.flash()});
} else {
res.render('fragments/block_posts', { posts: subset, user: req.session.user, message: req.flash()});
}
});