我有2个Mongoose集合:ExpenseCategory和Expense
var ExpenseCategorySchema = new Schema({
name: String,
totalSpentInThisMonth: Number
});
mongoose.model('ExpenseCategory', ExpenseCategorySchema);
var ExpenseSchema = new Schema({
expenseCategoryId: {type: Schema.Types.ObjectId, ref: 'ExpenseCategory'},
amount: Number,
date: Date
});
mongoose.model('Expense', ExpenseSchema);
在 Node.js 中写了GET api
次来回复所有ExpenseCategory items
。
appRouter.route('/expensecatgories')
.get(function(req, res){
ExpenseCategory.find({}, function (expenseCategories) {
res.json(expenseCategories);
});
});
在上面GET method
中,我希望在返回之前在每个totalSpentInThisMonth
项中填充字段expenseCategories
。此字段需要计算为所有expense.amount
的总和,其中expense.expenseCategoryId
与expenseCategory.id
和expense.date
在当月匹配。
如何在返回totalSpentInThisMonth
之前填充字段expenseCategories
?
答案 0 :(得分:0)
使用聚合框架中的 .aggregate()
方法。您需要首先构建日期,以用作日期范围在当前月份内的文档的日期范围查询,因此您需要进行计算
月份的第一天和最后一天约会对象。这些日期将用于 $match
管道中,以过滤掉当前月份以外的文档。
下一个管道流将是 $group
阶段,它按expenseCategoryId
键对传入文档进行分组,以便您可以使用以下内容计算当前月份的总支出
累加器运算符 $sum
。
以下代码实现了上述内容:
appRouter.route('/expensecatgories').get(function(req, res){
var today = new Date(), y = today.getFullYear(), m = today.getMonth();
var firstDay = new Date(y, m, 1);
var lastDay = new Date(y, m + 1, 0);
var pipeline = [
{
"$match": {
"date": { "$gte": firstDay, "$lt": lastDay }
}
},
{
"$group": {
"_id": "$expenseCategoryId",
"totalSpentInThisMonth": { "$sum": "$amount" }
}
}
];
Expense.aggregate(pipeline, function (err, result){
if (err) throw err;
var categories = result.map(function(doc) { return new ExpenseCategory(doc) });
Expense.populate(categories, { "path": "expenseCategoryId" }, function(err, results) {
if (err) throw err;
console.log(JSON.stringify(results, undefined, 4 ));
res.json(results);
});
});
});