Mongodb 可选 $match 管道运算符的聚合追加方法

Mongodb Aggregation Append method for optional $match pipeline operator

我在 mongodb 2.6 中使用 nodejs + mongoosejs。我在模型上有一个静态函数,该函数对集合中所有项目的值求和。使用 projectNo 属性 将每个项目分配给一个项目。我需要静态函数能够为我提供集合的总数,如果传递了 projectNo 参数,则将 $match 管道运算符添加到聚合中。这将使我不必制作 2 个本质上做同样事情的静态函数。

为了让事情更有趣一点,我使用 bluebird promisifyAll 方法使聚合框架 return 成为一个承诺。

我对整个集合求和的静态函数:

db.collection.aggregateAsync([ {$group:{_id: null, amount: { $sum: "$amount" }}} ])

我的静态函数仅对具有匹配项目编号的记录求和:

db.collection.aggregateAsync([ {$match: { projectNo: projectNo }}, {$group:{_id: null, amount: { $sum: "$amount" }}} ])

我真的想使用 Aggregate.append 方法仅在包含 req.params.projectNo 时附加 $match 管道。

当我尝试将它添加到异步聚合时出现错误,这是有道理的,因为它只是一个承诺。如果我试试这个:

db.collection.aggregateAsync([ {$group:{_id: null, amount: { $sum: "$amount" }}} ]).then(function(aggregate){ aggregate.append({$match: { projectNo: projectNo }}) })

我得到一个错误,(追加未定义)。我应该怎么做呢?或者只是接受我有两个功能做同样事情的事实?

我阅读了 mongodb 中的源代码,以了解如何使用 aggregate.append 方法。如果您使用链式方法构建聚合,则可以使用 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);

我通常把事情弄得比我需要的复杂得多...