如何在Mongoose中基于查询执行日期匹配文档?
Mongoose聚合管道中动态匹配当前日期的解决方案
方法一:让MongoDB自行计算当前日期(推荐)
直接利用MongoDB的系统变量与日期操作符,在查询执行时动态计算目标日期范围,彻底避免服务器启动时固定日期的问题。
比如要匹配createdAt字段为当天的文档,可以在$match阶段使用$expr结合$$NOW(代表查询执行时的当前时间)生成当天的起始和结束时间:
const pipeline = [ { $match: { $expr: { $and: [ // 匹配大于等于当天0点的文档 { $gte: ["$createdAt", { $dateFromParts: { year: { $year: "$$NOW" }, month: { $month: "$$NOW" }, day: { $dayOfMonth: "$$NOW" } }] }, // 匹配小于次日0点的文档 { $lt: ["$createdAt", { $dateAdd: { startDate: { $dateFromParts: { year: { $year: "$$NOW" }, month: { $month: "$$NOW" }, day: { $dayOfMonth: "$$NOW" } } }, unit: "day", amount: 1 } }] ] } } } ]; // 执行聚合查询 const result = await YourModel.aggregate(pipeline);
这种方式的优势是完全在数据库端计算日期,能避免服务器与数据库时区不一致导致的时间偏差,结果更准确。
方法二:将管道定义为函数,每次执行时生成新管道
如果更习惯在服务器端计算日期,可以把聚合管道封装成函数,每次执行查询时调用函数生成最新的管道,确保new Date()是查询执行时的当前时间:
const getTodayPipeline = () => { // 计算当天0点和次日0点 const todayStart = new Date(); todayStart.setHours(0, 0, 0, 0); const todayEnd = new Date(todayStart); todayEnd.setDate(todayEnd.getDate() + 1); return [ { $match: { createdAt: { $gte: todayStart, $lt: todayEnd } } } ]; }; // 每次查询时调用函数生成最新管道 const result = await YourModel.aggregate(getTodayPipeline());
内容的提问来源于stack exchange,提问作者Emanuele Paolini
相关产品推荐
相关产品推荐

