Reputation: 2412
I have two collections: question and answer. Each answer belongs to a question so an answer has its "question_id".
I like to get five questions which has most answers:
Answer.aggregate([
{
$group: {
_id: '$question_id',
num_questions: { $sum: 1 },
}
},
{
$sort: {
'num_questions': -1
}
}
]).then(function(answers) {
var result = [];
for(answer of answers) {
Question.findById(answer._id, function(err, question) {
result.push(question);
});
}
console.log(result);
res.json({questions: result});
});
but with the above code, my result will be null because of the async mechanism.
How can I get it done ?
Another problem that I had, with the aggregate query, I can only have questions that has at least one answer. How can I get the questions without answer ?
Upvotes: 0
Views: 50
Reputation: 5146
A better way would be using a Promise library like Q which helps you with these things. With Q it's easy to wait until all promises resolve without using extra shenanigans (like using a count variable)..
Answer.aggregate([
{
$group: {
_id: '$question_id',
num_questions: {$sum: 1}
}
},
{
$sort: {
'num_questions': -1
}
}
]).then(function (answers) {
var promises = [];
for (answer of answers) {
promises.push(Question.findById(answer._id).exec());
}
Q.all(promises).then(function(questions) {
res.json({'questions': questions});
});
});
Upvotes: 0
Reputation:
Answer.aggregate([
{
$group: {
_id: '$question_id',
num_questions: { $sum: 1 },
}
},
{
$sort: {
'num_questions': -1
}
}
]).then(function(answers) {
var result = [];
var count = 0;
for(answer of answers) {
Question.findById(answer._id, function(err, question) {
count++
result.push(question);
if (count == 5) {
res.json({questions: result});
}
});
}
console.log(result);
});
Upvotes: 1