Mongoose/MongoDB按天统计通话记录异常:查询结果始终为0的技术求助
问题分析与解决方案
嘿,我一眼就看到你代码里的问题了——Moment.js对象是可变的,这直接导致你的查询条件完全失效!
看这段关键代码:
const cdrIns = await CDRIn.find({ createdAt: { $gte: today, $lt: today.add(1, 'day') }, });
当你调用today.add(1, 'day')时,它不会返回新的日期对象,而是直接修改了today本身的值。所以你的查询条件实际上变成了:
createdAt: { $gte: 「加一天后的时间」, $lt: 「加一天后的时间」 }
这种范围完全重合的条件,自然匹配不到任何记录,结果肯定是0条。
修复方案
把日期范围的起止时间分开,并且用clone()避免修改原对象:
const startOfMonth = new moment().startOf('month'); const yesterday = new moment().subtract(1, 'day'); const now = startOfMonth.clone(); while (now.isSameOrBefore(yesterday)) { const todayStart = now.clone(); // 当天起始时间 const todayEnd = todayStart.clone().add(1, 'day'); // 当天结束时间(次日0点) const cdrIns = await CDRIn.find({ createdAt: { $gte: todayStart, $lt: todayEnd }, }); console.log(`There were ${cdrIns.length} calls on ${todayStart.toDate()}`) now.add(1, 'day'); }
额外排查点
如果修复后还是没有数据,建议检查这几点:
- 确认MongoDB中
CDRIn集合的createdAt字段是Date类型,而非字符串类型。如果是字符串,要么用对应字符串格式匹配,要么先把字段转换为Date类型。 - 验证时区一致性:Moment.js默认使用本地时区,要确认数据库里的
createdAt时间和代码时区是否一致。比如数据库用UTC的话,你可能需要改用moment.utc()来构建查询条件。 - 手动在Mongo Shell测试查询:比如针对某一天执行
db.CDRIn.find({createdAt: {$gte: ISODate("2022-09-22T00:00:00Z"), $lt: ISODate("2022-09-23T00:00:00Z")}}),看是否能返回数据,以此验证查询逻辑的正确性。
内容的提问来源于stack exchange,提问作者Alan Spurlock
相关产品推荐
相关产品推荐

