Spl*_*tty 5 mongodb node.js aggregation-framework
我在 mongodb 2.6 中使用 nodejs + mongoosejs。我在一个模型上有一个静态函数,可以对集合中所有项目的值求和。每个项目都使用 projectNo 属性分配给一个项目。我需要静态函数能够为我提供集合的总数,如果传递了 projectNo 参数,则向聚合添加 $match 管道运算符。这将使我不必制作 2 个基本上做同样事情的静态函数。
为了让事情更有趣,我使用 bluebird promisifyAll 方法让聚合框架返回一个承诺。
我对整个集合求和的静态函数:
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方法。如果您使用链式方法构建聚合,则可以使用追加来添加任何管道操作。
所以我所做的是将聚合管道数组放入一个数组中。如果有一个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);
Run Code Online (Sandbox Code Playgroud)
我通常让事情变得比我需要的更复杂......
| 归档时间: |
|
| 查看次数: |
989 次 |
| 最近记录: |