MongoDB中$lt操作符比较日期未按预期生效问题排查
MongoDB聚合查询$lt条件不生效问题
问题描述
我编写了一段聚合查询,用于对比当前日期与固定日期,若当前日期早于未来日期,则将result字段设置为"pass"。但实际执行时,$lt条件始终未被满足,result一直被设置为"fail"。
文档示例
[{ "future_date": { "$date": { "$numberLong": "62135596800000" } } }]
查询语句
db.collection.aggregate([{ "$addFields": { "current_date": new Date(), "future_date": new Date(62135596800000), "result": { $switch: { branches: [{ case: { "$lt": [new Date(), "$future_date"] }, then: "pass" }], default: "fail" } } } }])
执行结果
[{ "_id": ObjectId("5a934e000102030405000000"), "current_date": ISODate("2022-08-17T13:21:36.552Z"), "future_date": ISODate("3939-01-01T00:00:00Z"), "result": "fail" }]
问题原因与解决方法
问题出在$lt条件的写法上:你直接使用了客户端的new Date()来获取当前日期,而"$future_date"是聚合管道中的服务器端字段引用,两者上下文不同,导致对比逻辑失效。
MongoDB聚合管道中获取当前日期需要使用服务器端的内置变量$$NOW,或者$currentDate操作符。修正后的查询有两种写法:
写法一:使用$$NOW变量
db.collection.aggregate([{ "$addFields": { "current_date": "$$NOW", "future_date": new Date(62135596800000), "result": { $switch: { branches: [{ case: { "$lt": ["$$NOW", "$future_date"] }, then: "pass" }], default: "fail" } } } }])
写法二:使用$currentDate阶段
db.collection.aggregate([ { "$currentDate": { "current_date": true } }, { "$addFields": { "future_date": new Date(62135596800000), "result": { $switch: { branches: [{ case: { "$lt": ["$current_date", "$future_date"] }, then: "pass" }], default: "fail" } } } } ])
$$NOW会在聚合执行时由服务器计算当前日期时间,能和管道内的$future_date字段正确完成对比,这样result就能根据条件正确设置为"pass"。
内容的提问来源于stack exchange,提问作者Dan Cundy
相关产品推荐
相关产品推荐

