MongoDB如何通过两个字段(id和month)进行过滤,并且还通过所有过滤后的文档返回总和?

时间:2019-10-22 06:25:54

标签: node.js mongodb mongoose mongodb-query aggregation-framework

您好,我正在编写Node / Express端点,并且尝试使用Mongoose编写MongoDB查询,以返回当前日期或月份内过期的文档总和。

当前,我只是想返回当天的金额。

  • 首先,我要匹配包含用户ID的所有文档。
  • 然后我要匹配当天的所有文档。
  • 最后,我想针对所有这些返回$amount字段的总和 文档。

我知道这样做的语法是错误的,我很难找到与我的工作相匹配的示例。

let now = Date.now(),
    oneDay = 1000 * 60 * 60 * 24,
    today = new Date(now - (now % oneDay)),
    tomorrow = new Date(today.valueOf() + oneDay);

router.get("/user_current_month/:id", [jsonParser, jwtAuth], (req, res) => {
    return Expense.aggregate([
        {
            $match: { user: new mongoose.Types.ObjectId(req.params.id) }
        },
        {
            $match: {
                $expiration: {
                    $gte: today,
                    $lt: tomorrow
                }
            }
        },
        {
            $group: {
                _id: "$month",
                total: {
                    $sum: "$amount"
                }
            }
        }
    ])
        .then(sum => {
            res.status(200).json(sum);
        })
        .catch(err => res.status(500).json({ message: "Something went terribly wrong!" }));
});

这是文档的样子:

{
    "_id": {
        "$oid": "5daea018b3d92643fc2c8e6c"
    },
    "user": {
        "$oid": "5d9929f065ef083d2cdbf66c"
    },
    "expense": "Post 1",
    "expenseType": "One Time",
    "notes": "",
    "amount": {
        "$numberDecimal": "100"
    },
    "expiration": {
        "$date": "2019-10-22T06:22:01.628Z"
    },
    "status": "Active",
    "createdAt": {
        "$date": "2019-10-22T06:22:16.644Z"
    },
    "__v": 0
}

1 个答案:

答案 0 :(得分:2)

您需要在AND子句中传递两个匹配表达式,然后进行分组以执行加法运算。您需要执行以下操作:

Expense.aggregate([
    { $match: { $and: [{ user: new mongoose.Types.ObjectId(req.params.id) },
   {
                $expiration: {
                    $gte: today,
                    $lt: tomorrow
                }
            } ]}},
    { $group: {
            _id: "$month",
            total: {
                $sum: "$amount"
            }
        }}
    ]);