MongoDB两个日期区间内匹配文档查询的问题排查
问题原因
你的查询条件判断方向写反了,同时存储的日期字段存在类型隐患。
- 逻辑方向错误:当前写法里的
fromDate : {'$gte': new Date(fromDate)}要求文档存储的活动开始时间晚于/等于传入的查询开始时间,toDate : {'$lte': new Date(toDate)}要求文档存储的活动结束时间早于/等于传入的查询结束时间。这个逻辑只会匹配「文档时间区间完全被传入的查询时间区间包裹」的场景,和你要的「传入时间落在文档存储的活动区间内」的需求完全相反。
拿你测试失败的场景举例:文档存储的fromDate是2022-07-07,传入的查询fromDate是2022-08-08,判断条件2022-07-07 >= 2022-08-08显然不成立,自然查不到结果。 - 类型隐患:当前集合里存的
fromDate、toDate是字符串格式,不是MongoDB原生Date类型。虽然ISO标准格式的日期字符串字典序和时间先后顺序一致,暂时不会出现比较错误,但后续如果写入非标准格式的日期字符串,很容易出现比较结果异常,建议提前将存量数据的这两个字段转换为原生Date类型,后续写入也直接存Date类型,避免隐式转换带来的问题。
正确查询写法
要实现「传入的起止日期完全落在文档存储的fromDate-toDate区间内(含边界)即返回结果」的需求,把两个比较条件的判断方向调换即可,代码如下:
busTicketPromotions.find({ fromDate : {'$lte': new Date(queryFromDate)}, // 活动开始时间早于/等于查询开始时间:查询起点时活动已生效 toDate : {'$gte': new Date(queryToDate) } // 活动结束时间晚于/等于查询结束时间:查询终点时活动未失效 });
调整后两个测试场景都能正常命中:
- 传入起止时间和文档完全相等时:
2022-07-07 <= 2022-07-07、2022-12-12 >= 2022-12-12,条件成立 - 传入起止时间在文档区间内部时:
2022-07-07 <= 2022-08-08、2022-12-12 >= 2022-11-11,条件成立
内容的提问来源于stack exchange,提问作者Usman Iqbal
相关产品推荐
相关产品推荐

