使用$gte/$lte查询MongoDB日期数据返回空集问题排查
排查方案
- 核对日期字符串的解析差异
前端传的departureDateMin/departureDateMax如果是YYYY-MM-DD这类格式,new Date()在不同时区环境下的解析结果不一样——比如东八区环境下,new Date('2024-05-01')会被解析为2024-04-30T16:00:00.000Z(UTC时间),但Compass里用ISODate('2024-05-01')是2024-05-01T00:00:00.000Z,两者差了8小时,导致查询范围完全不匹配,自然查不到数据。 - 打印实际生成的查询条件
在代码里加一行console.log(queryMatch),查看$gte和$lte对应的Date对象的UTC字符串,和Compass里用的ISODate值对比,就能直接看出是不是时区解析的问题。 - 强制用UTC时间构造查询条件
手动把日期字符串拼接成UTC格式的时间,避免时区干扰:
这样构造的Date对象和Compass里的ISODate完全一致,因为ISODate本质就是UTC标准时间。// 假设传入的日期是'YYYY-MM-DD'格式 const minDate = new Date(`${query.departureDateMin}T00:00:00.000Z`); const maxDate = new Date(`${query.departureDateMax}T23:59:59.999Z`); const queryMatch = { departureDate: { $gte: minDate, $lte: maxDate } }; - 检查数据库字段类型
确认departureDate字段存的是ISODate类型,不是字符串。如果是字符串类型,MongoDB在Compass里用ISODate查询时可能会做隐式类型转换,但代码里的Date对象和字符串直接对比会失效,这种情况需要把数据库字段改成Date类型,或者代码里把查询条件转成字符串匹配。 - 确认边界值覆盖范围
如果departureDateMax是2024-05-05,直接用new Date(query.departureDateMax)会生成当天0点的UTC时间,数据库里当天晚些时候的记录会被排除。改成${query.departureDateMax}T23:59:59.999Z就能包含当天所有UTC时间的记录。
内容的提问来源于stack exchange,提问作者MoTra
相关产品推荐
相关产品推荐

