使用Mongoose查询MongoDB日期范围时无结果的问题
解决MongoDB日期范围查询无结果的问题
问题本质
MongoDB的BSON Date类型存储的是UTC时间戳,所有插入的日期最终都会转换为UTC存储。你的Rust程序使用EST本地时间插入数据,实际存储的是EST转UTC后的时间(例如EST的2023-05-21 06:37:21会被转成UTC的2023-05-21T10:37:21.270+00:00)。而查询时你传入的EST时间戳被直接转换为UTC时间对象,导致查询范围偏移了4小时(EST与UTC的时差),因此无法匹配到存储的UTC时间。
另外,使用toLocaleString将日期转为字符串查询是错误的——MongoDB的Date字段需要与Date类型(或ISO格式字符串)比较,字符串比较会按字典序处理,无法正确匹配时间范围。
解决方案
1. 修正查询逻辑:将EST时间转换为UTC时间查询
如果传入的startTime和endTime是EST时区的时间戳,需要先将其转换为对应的UTC时间戳,再构建查询条件:
async getPerfDataForServer(serverName: string, startTime: number, endTime: number): Promise<Perf[]> { // EST/EDT与UTC的时差:EDT比UTC晚4小时(夏令时),EST标准时间晚5小时,根据实际时区调整 const EST_UTC_OFFSET = -4 * 60 * 60 * 1000; // 单位:毫秒,负号表示比UTC晚 // 将EST时间戳转换为UTC时间戳 const utcStartTimestamp = startTime - EST_UTC_OFFSET; const utcEndTimestamp = endTime - EST_UTC_OFFSET; // 转换为Date对象用于查询 const startDateTime = new Date(utcStartTimestamp); const endDateTime = new Date(utcEndTimestamp); const query = { hostname: serverName, datetime: { $gte: startDateTime, $lte: endDateTime } }; const perfData = await this.perfModel.find(query).exec(); return perfData || []; }
2. 确保数据插入的正确性(修正Rust代码)
确认Rust程序在插入数据时,已将EST本地时间正确转换为UTC后再存入MongoDB:
use chrono::{Local, Utc}; use bson::DateTime; // 获取EST本地时间并转换为UTC let local_time = Local::now(); let utc_time = local_time.with_timezone(&Utc); // 转换为BSON Date类型 let bson_date = DateTime::from_utc(utc_time.naive_utc()); // 将bson_date插入MongoDB的datetime字段
3. 额外提示
Mongoose默认会将Date对象转换为UTC进行存储和查询,不要手动修改Mongoose的时区配置,只需确保查询用的Date对象是目标时间范围对应的UTC时间即可。
内容的提问来源于stack exchange,提问作者Tushar Saurabh
相关产品推荐
相关产品推荐

