API 返回匹配的日期以及与指定日期不匹配的日期

问题描述 投票:0回答:3

我正在用nodejs开发一个api。 我有以下结构的文档:

{
    "_id" : ObjectId("5ecd26504df3372a38afffd9"),
    "balance" : 104000,
    "bankID" : "Bank-1",
    "userEmail" : "[email protected]",
    "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
}

我只需要提取从日期=“20/07/2020”到日期=“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": "[email protected]",
            "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
      }

但是,我正在获取所有交易。 我什至尝试传递日期,从日期=“20-07-2020”到日期=“31-07-2020”。这也会返回所有交易。

DB中存储的所有日期都是String类型。

node.js mongodb mongoose
3个回答
3
投票

问题是你的日期格式。由于您在数据库中保存的数据中以

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
投票

你就快到了。问题出在你的数据上。它的日期格式无效。

蒙戈游乐场

我将其中一笔交易更改为正确的日期格式,如下所示

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

mongo 日期格式

因此,如果格式正确,查询就会起作用。

new Date("<YYYY-mm-dd>")
返回指定日期的 ISODate。

new Date("<YYYY-mm-ddTHH:MM:ss>")
指定客户端本地时区的日期时间,并返回具有 UTC 指定日期时间的 ISODate。

new Date("<YYYY-mm-ddTHH:MM:ssZ>")
指定 UTC 日期时间并返回具有指定 UTC 日期时间的 ISODate。

new Date(<integer>)
将日期时间指定为自 Unix 纪元(1970 年 1 月 1 日)以来的毫秒数,并返回生成的 ISODate 实例。


1
投票

建议一些修复,

  • 使用
    new Date("2020-07-31")
    ,
  • 将字符串日期转换为 ISO 日期
var trailBalance = {
    userEmail: req.body.userEmail,
    fromDate: new Date(req.body.fromDate),
    toDate: new Date(req.body.toDate),
};
  • 使用
    $dateFromString
    将集合的字段 transactions.date
  • 字符串转换为 ISO 日期
  • 格式:
    %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
                ]
              }
            ]
          }
        }
      }
    }
  }
]);
© www.soinside.com 2019 - 2024. All rights reserved.