API возвращает дату, которая соответствует, а также даты, которые не соответствуют указанной дате - PullRequest
1 голос
/ 01 августа 2020

Я разрабатываю api на nodejs. У меня есть документ в следующей структуре:

{
    "_id" : ObjectId("5ecd26504df3372a38afffd9"),
    "balance" : 104000,
    "bankID" : "Bank-1",
    "userEmail" : "kumarshreyas073@gmail.com",
    "bankName" : "Corporation Bank",
    "accountNumber" : "03214569874563",
    "ifsCode" : "CORP0001236",
    "branch" : "Udupi",
    "address" : "Udupi",
    "city" : "Udupi",
    "state" : "Karnataka",
    "openingBalance" : 100000,
    "transactions" : [ 
        {
            "credit" : 2000,
            "debit" : 0,
            "_id" : ObjectId("5ecd26614df3372a38afffea"),
            "transactionID" : "CashTransaction-5ecd26614df3372a38afffe8",
            "date" : "30-05-2026",
            "particulars" : "By Cash-1",
            "voucherType" : "Cash"
        }, 
        {
            "credit" : 0,
            "debit" : 2000,
            "_id" : ObjectId("5ecd272d4df3372a38b00012"),
            "transactionID" : "Receipt-5ecd272d4df3372a38b00009",
            "date" : "29-07-2020",
            "particulars" : "To Suresh kumar",
            "voucherType" : "Receipt"
        }, 
        {
            "credit" : 0,
            "debit" : 2000,
            "_id" : ObjectId("5ecd272d4df3372a38b00014"),
            "transactionID" : "Receipt-5ecd272d4df3372a38b00003",
            "date" : "30-05-2024",
            "particulars" : "To Karthik",
            "voucherType" : "Receipt"
        }
    ],
    "idCounter" : 1,
    "__v" : 0
}

Мне нужно извлечь только те транзакции между from date = «20/07/2020» и до date = «31/07/2020».

Код, который я написал, выглядит следующим образом:

exports.trail_balance = async (req, res, next) => {
  var trailBalance = {
    userEmail: req.body.userEmail,
    fromDate: req.body.fromDate,
    toDate: req.body.toDate,
  };

var bankAccount = await Bank.aggregate([
    { $match: { userEmail: req.body.userEmail } },
    {
      $addFields: {
        transactions: {
          $filter: {
            input: "$transactions",
            as: "transactions",
            cond: {
              $and: [
                {
                  $gte: ["$$transactions.date", trailBalance.fromDate],
                },

                {
                  $lte: ["$$transactions.date", trailBalance.toDate],
                },
              ],
            },
          },
        },
      },
    },
  ]);

res.status(200).json({
    result: 1,
    bankAccount: bankAccount.length > 0 ? bankAccount : [], 
  });
};

Фактический результат, который я ожидаю, будет:

{
    "result": 1,
    "bankAccount": [
        {
            "_id": "5ecd26504df3372a38afffd9",
            "balance": 104000,
            "bankID": "Bank-1",
            "userEmail": "kumarshreyas073@gmail.com",
            "bankName": "Corporation Bank",
            "accountNumber": "03214569874563",
            "ifsCode": "CORP0001236",
            "branch": "Udupi",
            "address": "Udupi",
            "city": "Udupi",
            "state": "Karnataka",
            "openingBalance": 100000,
            "transactions": [
                {
                   "credit" : 0,
                   "debit" : 2000,
                   "_id" : ObjectId("5ecd272d4df3372a38b00012"),
                   "transactionID" : "Receipt-5ecd272d4df3372a38b00009",
                   "date" : "29-07-2020",
                   "particulars" : "To Suresh kumar",
                   "voucherType" : "Receipt"
               }
            ],
            "idCounter": 1,
            "__v": 0
      }

Но я получаю все транзакции. Я даже попытался передать дату, from date = "20-07-2020" и to date = "31-07-2020". Это тоже возвращает всю транзакцию.

Все данные, хранящиеся в БД, имеют тип String.

Ответы [ 3 ]

3 голосов
/ 01 августа 2020

Проблема в вашем формате даты. Поскольку вы начали дату с day в ваших сохраненных данных в базе данных, а тип даты - string, поэтому по сравнению с вашим запросом он всегда начинается с дня и это неверно. потому что при сравнении дат сначала нужно сравнивать годы, затем месяцы и, наконец, день. Но вы делаете это неправильно.

В этом сценарии mongodb выполняет запись! потому что в вашем from date, 2 меньше или равно 2 и 3, а в вашем to date 3 больше или равно 2 и 3. Так что все идет хорошо.

Я изменил формат даты ваших сохраненных данных на yyyy-mm-dd, и ваш запрос был правильным.

Если изменение данных для вас невозможно, вы также можете изменить данные в этап конвейера вашего запроса aggregate. Воспользуйтесь ссылкой ниже:

https://docs.mongodb.com/manual/reference/operator/aggregation/dateFromString/

2 голосов
/ 01 августа 2020

Предлагает несколько исправлений,

  • преобразовать дату строки в дату ISO, используя new Date("2020-07-31"),
var trailBalance = {
    userEmail: req.body.userEmail,
    fromDate: new Date(req.body.fromDate),
    toDate: new Date(req.body.toDate),
};
  • преобразовать поле коллекции transactions.date строка в дату ISO, используя $ dateFromString
  • формат: %d-%m-%Y должен соответствовать точному формату даты в transactions.date
{
    $dateFromString: {
        dateString: "$$transactions.date",
        format: "%d-%m-%Y"
    }
}

Посмотрите на рабочую площадку : https://mongoplayground.net/p/-KWgRCSwD8h

  • Ваш последний запрос,
var bankAccount = await Bank.aggregate([
  {
    $match: {
      userEmail: trailBalance.userEmail
    }
  },
  {
    $addFields: {
      transactions: {
        $filter: {
          input: "$transactions",
          as: "transactions",
          cond: {
            $and: [
              {
                $gte: [
                  {
                    $dateFromString: {
                      dateString: "$$transactions.date",
                      format: "%d-%m-%Y"
                    }
                  },
                  trailBalance.fromDate
                ]
              },
              {
                $lte: [
                  {
                    $dateFromString: {
                      dateString: "$$transactions.date",
                      format: "%d-%m-%Y"
                    }
                  },
                  trailBalance.toDate
                ]
              }
            ]
          }
        }
      }
    }
  }
]);
2 голосов
/ 01 августа 2020

Вы почти у цели. Проблема в ваших данных. Он имеет недопустимый формат даты.

понедельник go площадка

Я изменил формат даты на правильный формат для одной из транзакций, как показано ниже

"date": ISODate("2026-05-30"),

пн go формат даты

Итак, если у вас правильный формат, запрос будет работать.

new Date("<YYYY-mm-dd>") возвращает ISODate с указанным date.

new Date("<YYYY-mm-ddTHH:MM:ss>") указывает дату и время в локальном часовом поясе клиента и возвращает ISODate с указанным datetime в UT C.

new Date("<YYYY-mm-ddTHH:MM:ssZ>") указывает дату и время в UT C и возвращает ISODate с указанной датой и временем в UT C.

new Date(<integer>) указывает дату и время в миллисекундах с момента Unix эпоха (1 января 1970 г.) и возвращает получившийся экземпляр ISODate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...