MongoDB, как отфильтровать по двум полям (id и месяц), а также вернуть сумму по всем отфильтрованным документам? - PullRequest
0 голосов
/ 22 октября 2019

Привет! Я работаю над написанием конечной точки Node / Express и пытаюсь написать запрос MongoDB, используя Mongoose, чтобы вернуть сумму значений моих документов, срок действия которых истек в течение текущего дня или месяца.

В настоящее время я просто пытаюсь вернуть сумму за текущий день.

  • Сначала я хочу сопоставить все документы, содержащие идентификатор пользователя.
  • ЗатемЯ хочу сопоставить все документы за текущий день.
  • Наконец, я хочу вернуть сумму поля $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 Ответ

2 голосов
/ 22 октября 2019

Вам нужно передать два выражения соответствия в предложении AND, а затем сгруппировать для выполнения операции сложения. Вам нужно сделать что-то вроде этого:

Expense.aggregate([
    { $match: { $and: [{ user: new mongoose.Types.ObjectId(req.params.id) },
   {
                $expiration: {
                    $gte: today,
                    $lt: tomorrow
                }
            } ]}},
    { $group: {
            _id: "$month",
            total: {
                $sum: "$amount"
            }
        }}
    ]);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...