我正在尝试通过开始使用
$unwind
来破坏日期数组来过滤一些日期数据:
"startDates": [
"2024-05-15T09:30:00.000Z",
"2024-11-13T10:00:00.000Z",
"2024-02-10T00:00:00.000Z"
]
使用:
{
$unwind: "$startDates",
},
然后使用
$match
过滤年份数据:
{
$match: {
startDates: {
$gte: new Date(`${year}-01-01`),
$lte: new Date(`${year}-12-31`),
},
},
},
但是响应返回一个空数组
{
"status": "Success",
"result": 0,
"data": {
"plan": []
}
}
但是当我删除
new Date
并手动写入日期时,响应返回我想要的数据
像这样:
{
$match: {
startDates: {
$gte: `${year}-01-01`,
$lte: `${year}-12-31`,
},
},
},
但是当我尝试使用
$group
对数据进行分组并使用 $month
pupline 时,它会向我显示以下错误:
{
"status": "failed",
"message": "PlanExecutor error during aggregation :: caused by :: can't convert from BSON type string to Date"
}
这是完整的功能代码:
exports.getMonthlyPlan = async (req, res) => {
try {
const year = req.params.year * 1;
const plan = await Tour.aggregate([{
$unwind: "$startDates",
},
{
$match: {
startDates: {
$gte: `${year}-01-01`,
$lte: `${year}-12-31`,
},
},
},
{
$group: {
_id: {
$month: "$startDates"
},
numTourStarts: {
$sum: 1
},
},
},
]);
res.status(200).json({
status: "Success",
result: plan.length,
data: {
plan,
},
});
} catch (error) {
res.status(400).json({
status: "failed",
message: error.message,
});
}
};
我希望我已经清楚地解释了这些问题
我正在尝试使用
new Date
功能,但我不明白这个问题
将日期值存储为字符串是一个设计缺陷,您不应该永远这样做。始终存储正确的
Date
物品。
首先,您可以通过如下更新来转换数据类型:
db.collection.updateMany(
{ startDates: { $type: "string" } },
[
{
$set: {
startDates: {
$map: {
input: "$startDates",
in: { $dateFromString: { dateString: "$$this" } }
}
}
}
}
]
)
然后你的查询就会起作用。这个可能会提供更好的性能:
db.gcollection.aggregate([
{
$match: {
startDates: {
$gte: new Date(`${year}-01-01`),
$lte: new Date(`${year}-12-31`)
}
}
},
{
$set: {
startDates: {
$filter: {
input: "$startDates",
cond: { $eq: [{ $year: "$$this" }, year] }
}
}
}
},
{ $unwind: "$startDates" },
{
$group: {
_id: { $month: "$startDates" },
numTourStarts: { $count: {} }
}
}
])