【问题标题】:Passing callback function to mongoose aggregate function将回调函数传递给 mongoose 聚合函数
【发布时间】:2015-04-08 01:37:29
【问题描述】:

我正在形成要在 aggregate() 中执行的查询,如下所示:

query.$project = {};
query.$project.created_at = '$created_at';
query.$project.month = {};
query.$project.month.$month = currentMonth;
query.$match = {};
query.$match.month = currentMonth.getMonth() + 1;
query.$limit = 5;
query.$sort = {};
query.$sort.created_at = -1;
query.callback = function(err, result){
    // do something
};
console.dir(query);

但是当我执行以下操作时:

DataTable.aggregate(query);

我明白了:

Error: Arguments must be aggregate pipeline operators
    at Aggregate.append (C:\myproject\node_modules\mongoose\lib\aggregate.js:87:11)
    at new Aggregate (C:\myproject\node_modules\mongoose\lib\aggregate.js:47:17)
    at Function.aggregate (C:\myproject\node_modules\mongoose\lib\model.js:1889:17)
    at C:\myproject\app\routes.js:179:23
    at C:\myproject\node_modules\async\lib\async.js:570:21
    at C:\myproject\node_modules\async\lib\async.js:249:17
    at C:\myproject\node_modules\async\lib\async.js:125:13

我现在有两个问题:

  • 有没有更好的方法来形成这个查询。
  • 以及如何在这里指定回调函数。

编辑

我将上面的代码修改如下:

query.$project = {};
query.$project.created_at = '$created_at';
query.$project.month = {};
query.$project.month.$month = currentMonth;
query.$match = {};
query.$match.month = currentMonth.getMonth() + 1;
query.$limit = 5;
query.$sort = {};
query.$sort.created_at = -1;

但是当我执行以下操作时:

DataTable.aggregate(query, function(err, result){
    // do something
});

【问题讨论】:

  • 您构造的查询对象看起来像:{$project:{},$match:{},$sort:{}},这是不正确的。而构造正确的查询可能看起来像:@thefourtheye 提到的以下答案:[{$project:{}},{$match:{}}]

标签: javascript node.js mongodb mongoose


【解决方案1】:

引用Mongoose's documentation for aggregate

参数:

  1. [...] <Object, Array>聚合管道运算符或运算符数组

  2. [callback] <Function>

期待你通过

  1. 聚合管道运算符数组

    DataTable.aggregate([{
        $project: {
            created_at: '$created_at',
            month: {
                $month: currentMonth
            }
        }
    }, {
        $match: {
            month: currentMonth.getMonth() + 1
        }
    }, {
        $limit: 5
    }, {
        $sort: {
            created_at: -1
        }
    }], function(err, result) {
    
    });
    
  2. 或多个聚合管道运算符作为单独的参数传递

    DataTable.aggregate({
        $project: {
            created_at: '$created_at',
            month: {
                $month: currentMonth
            }
        }
    }, {
        $match: {
            month: currentMonth.getMonth() + 1
        }
    }, {
        $limit: 5
    }, {
        $sort: {
            created_at: -1
        }
    }, function(err, result) {
    
    });
    

我更喜欢管道构建器的方式,

DataTable.aggregate().project({
    created_at: '$created_at',
    month: {
        $month: currentMonth
    }
}).match({
    month: currentMonth.getMonth() + 1
}).limit(5).sort({
    created_at: -1
}).exec(function(err, result) {

});

编辑:如果您喜欢单独准备单个项目,那么您可以使用数组对象,像这样

var query = [];

query.push({
    $project: {
        created_at: '$created_at',
        month: {
            $month: currentMonth
        }
    }
});

query.push({
    $match: {
        month: currentMonth.getMonth() + 1
    }
});

query.push({
    $limit: 5
});

query.push({
    $sort: {
        created_at: -1
    }
});

DataTable.aggregate(query, function(err, result) {

});

或者使用管道生成器,

var aggregator = DataTable.aggregate();
...
aggregator = aggregator.project({...});
...
aggregator = aggregator.match({...});
...
aggregator = aggregator.limit(...);
...
aggregator = aggregator.sort(...);
...
aggregator.exec(function(err, result) {

});

【讨论】:

  • 可以按照我形成查询的方式完成吗?我对这种语法有疑问。
  • @jsbisht 将我们在第一个方法中传递的数组存储在一个变量中。这对你有用吗?
  • @jsbisht 我的意思是this。我也将此方法添加到答案中。
  • 我试了一下,结果还是一样。
  • @jsbisht 你能说明你到底尝试了什么吗?
猜你喜欢
  • 2017-12-10
  • 2021-05-25
  • 1970-01-01
  • 1970-01-01
  • 2023-03-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多