我正在用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类型。
问题是你的日期格式。由于您在数据库中保存的数据中以
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/
你就快到了。问题出在你的数据上。它的日期格式无效。
我将其中一笔交易更改为正确的日期格式,如下所示
"date": ISODate("2026-05-30"),
因此,如果格式正确,查询就会起作用。
返回指定日期的 ISODate。new Date("<YYYY-mm-dd>")
指定客户端本地时区的日期时间,并返回具有 UTC 指定日期时间的 ISODate。new Date("<YYYY-mm-ddTHH:MM:ss>")
指定 UTC 日期时间并返回具有指定 UTC 日期时间的 ISODate。new Date("<YYYY-mm-ddTHH:MM:ssZ>")
将日期时间指定为自 Unix 纪元(1970 年 1 月 1 日)以来的毫秒数,并返回生成的 ISODate 实例。new Date(<integer>)
建议一些修复,
new Date("2020-07-31")
,var trailBalance = {
userEmail: req.body.userEmail,
fromDate: new Date(req.body.fromDate),
toDate: new Date(req.body.toDate),
};
$dateFromString将集合的字段
transactions.date
%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
]
}
]
}
}
}
}
}
]);