如何查询Mongoose中created_at时间戳为查询当日的文档
Mongoose查询当日创建文档的最佳实现
原查询失效原因
find({created_at: new Date()})无法返回结果的核心原因是:new Date()生成的是代码执行瞬间的毫秒级精确时间,而开启timestamps: true后Mongoose自动写入的created_at是文档插入时刻的毫秒级时间,两个时间值几乎不可能完全相等,自然无法匹配到当日早些时候插入的文档。
方案1:时间范围查询(生产环境首选)
该方案不会对存储的字段做运算,可完全命中created_at字段上的索引,查询性能最优。
核心逻辑是构造当日零点、次日零点两个时间边界,查询created_at落在半开区间内的所有文档即可:
// 生成查询当日0点0分0秒0毫秒的时间 const startOfDay = new Date(); startOfDay.setHours(0, 0, 0, 0); // 生成次日0点0分0秒0毫秒的时间 const endOfDay = new Date(startOfDay); endOfDay.setDate(endOfDay.getDate() + 1); // 执行查询 const todayData = await YourModel.find({ created_at: { $gte: startOfDay, $lt: endOfDay } });
注意边界匹配要使用
$lt(小于)而非$lte(小于等于)关联次日零点,不要用$lte: 当日23:59:59.999的写法:后者会受时间精度、时区配置影响,容易漏掉当日最后几毫秒写入的文档,前者边界逻辑更严谨无漏洞。
方案2:日期截断匹配(适合聚合场景)
如果使用MongoDB 5.0及以上版本,且在聚合管道中需要做日期维度的匹配,可以用$dateTrunc运算符直接将时间戳截断到日维度做匹配:
const todayData = await YourModel.aggregate([ { $match: { $expr: { $eq: [ { $dateTrunc: { date: "$created_at", unit: "day" } }, startOfDay // 复用前面生成的当日零点时间即可 ] } } } ]);
注意事项
- 如果你的Mongoose schema里自定义了时间戳字段名,要保证查询字段和配置一致,Mongoose默认生成的创建时间字段为
createdAt,若重命名为created_at需要在schema中显式配置:
const customSchema = new Schema( { /* 业务字段定义 */ }, { timestamps: { createdAt: "created_at", updatedAt: "updated_at" } } );
- 单表数据量超过百万级时,提前为
created_at字段创建升序索引,可将查询耗时从秒级降到毫秒级。
内容的提问来源于stack exchange,提问作者Chris S
相关产品推荐
相关产品推荐

