【问题标题】:Mongoose, Node.js get sum of a field from a bunch of documentsMongoose,Node.js 从一堆文档中获取一个字段的总和
【发布时间】:2019-03-27 10:58:40
【问题描述】:

我有这个猫鼬方法/查询,它可以从某个用户那里找到所有“收入”,但前提是“收入”的日期在当月之内。

代码:

module.exports.getMonthlyIncome = function(userId, callback){
const now = new Date();

const year = now.getFullYear();
const month = now.getMonth();
const date = now.getDate();

const start = new Date(year, month, 1);
const end = new Date(year, month, 30);

Income.find({owner: userId, date: { $gte: start, $lt: end }}, callback);
}

结果:

[
{

"_id": "58cc9ee50fe27e0d2ced5193",
"amount": 600,
"description": "Ripco Salary",
"owner": "58cc9e950fe27e0d2ced5192",
"__v": 0,
"date": "2017-03-17T00:00:00.000Z"
},

{

"_id": "58ccc3cfca6ea10980480d42",
"amount": 450,
"description": "Another Ripped co salary",
"owner": "58cc9e950fe27e0d2ced5192",
"__v": 0,
"date": "2017-03-26T00:00:00.000Z"
}

]

结果如预期,给了我一个月内属于某个用户的2份收入文件。

现在,我想从这些文档中获取每个“金额”字段的总和。

所以在这种情况下,总和是 1050。

我将如何在 Mongoose 中实现这一点?

非常感谢任何帮助,干杯。

【问题讨论】:

    标签: node.js mongodb mongoose


    【解决方案1】:

    您可以使用mongoose Aggregation pipeline 计算多个文档中amount 的总和。

    你需要使用$match,匹配查询条件,$group计算多个文档的总和。

    Income.aggregate([{
        $match : { $and : [ {owner: userId}, {date: { $gte: start, $lt: end } }] },
    },{
        $group : {
            _id : null,
            total : {
                $sum : "$amount"
            }
        }
    }],callback);
    

    希望这会有所帮助!

    【讨论】:

    • 您的代码中存在小错误:$match : { $and : [ {owner: userId, date: { $gte: start, $lt: end } }] },
    • @krekto 谢谢,我更新了。完全没有看到那个错误
    • 需要$and 吗?默认情况下有多个条件 and 表达式,不是吗?所以$match : { owner: userId, date: { $gte: start, $lt: end } } 应该也一样,对吧?
    【解决方案2】:

    有两种方法可以做到这一点。

    1.使用聚合查询: 看起来你是 mongodb 的新手。所以,我不会为你推荐这种方法。这种方法在另一个答案中得到了正确的介绍,应该可以正常工作。一定要看看!

    2。使用underscore-node

    重写你的代码:

    module.exports.getMonthlyIncome = function(userId, callback){
    const now = new Date();
    
    const year = now.getFullYear();
    const month = now.getMonth();
    const date = now.getDate();
    
    const start = new Date(year, month, 1);
    const end = new Date(year, month, 30);
    // Including underscore-node
    const _ = require('underscore-node');
    Income.find({owner: userId, date: { $gte: start, $lt: end }}, function(err, results){
       if (err) {
        //handle error
       }
    
       let sum = _.reduce(results, function(memo, reading){ return memo + reading.amount; }, 0);
       // Explaination:
       // reduce() accepts an array and a callback function.
       // So, we are passing the array in "results"
       // In the callback function, do not touch "memo" variable
       // Every single object in "results" array will be passed 
       // to callback function in the "reading" variable
    });
    

    希望此代码对您有所帮助!

    【讨论】:

    • 你也可以使用原生的array.reduce函数
    猜你喜欢
    • 2021-08-30
    • 2021-10-05
    • 2021-11-15
    • 2021-06-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-07-20
    • 1970-01-01
    相关资源
    最近更新 更多