MongoDB 聚合:可选的 $match 管道操作符的追加方法

5
我正在使用Node.js + Mongoose.js与MongoDB 2.6。我的模型上有一个静态函数,用于计算集合中所有项的值之和。每个项都使用一个projectNo属性分配给一个项目。我需要使静态函数能够为我提供集合的总计,并且如果传递了一个projectNo参数,则添加$match管道运算符进行聚合。这将使我不必编写两个本质上执行相同操作的静态函数。
为了增强功能,我使用了bluebird promisifyAll方法,以使聚合框架返回一个Promise。
以下是计算整个集合的静态函数: db.collection.aggregateAsync([ {$group:{_id: null, amount: { $sum: "$amount" }}} ]) 以下是仅计算具有匹配projectNo的记录的静态函数: db.collection.aggregateAsync([ {$match: { projectNo: projectNo }}, {$group:{_id: null, amount: { $sum: "$amount" }}} ]) 我真的想使用Aggregate.append方法,只有在req.params.projectNo中包含时才附加$match管道。
当我尝试将它添加到异步聚合中时,会出现错误,这很合理,因为它只是一个promise。如果我尝试这样做:
db.collection.aggregateAsync([     {$ group:{_id:null,amount:{ $sum:“$ amount” }}} ]).then(function(aggregate){     aggregate.append({$ match:{projectNo:projectNo }}}) })
我会得到一个错误(不定义附加)。我应该怎么做呢?还是要接受我有两个执行相同操作的函数的事实?

我不介意在这里得到一点帮助。使其与 promises 兼容并非必需。 - Splitty
1个回答

4
我阅读了mongodb的源代码,以确切地了解如何使用聚合附加方法。如果您正在使用链接方法构建聚合,则可以使用append添加任何流水线操作。
因此,我将聚合管道数组放入数组中。如果有projectNo,则使用unshift()将$match流水线添加到数组中。我使用unshift,因为通常希望$match流水线首先限制记录数量,然后执行其余的流水线操作。
var pipeline = [{$group:{_id: null, amount: { $sum: "$amount" }}}];
if(req.params.projectNo){
    pipeline.unshift({$match: { projectNo: req.params.projectNo }});
}
db.collection.aggregateAsync(pipeline);

通常我会把事情搞得比必要的还要复杂...


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接