如何在MongoDB查询中嵌入日期转时间戳的转换逻辑?
在MongoDB查询中实现日期转时间戳的正确方式
你遇到的问题核心是:MongoDB的普通查询过滤器(find的第一个参数)不支持在查询条件里直接使用聚合操作符(比如$toLong),所以你之前的写法会被MongoDB当成一个普通的文档来和ts字段对比,自然返回空结果。下面给你几种可行的解决方案,根据你的时间戳单位(秒/毫秒)来选择:
1. 最简单的方案:直接用Date对象(推荐)
MongoDB会自动处理Date对象和时间戳数字的对比,但要注意你的ts字段是秒级还是毫秒级时间戳:
情况A:ts是毫秒级时间戳(数字)
直接传入new Date()生成的对象即可,MongoDB会自动把它转换成对应的毫秒数来做对比:
db.my_collection.find({"ts": {$lt: new Date("2020-12-09")}})
这里new Date("2020-12-09")默认生成的是UTC时区的该日期零点,如果你需要对应本地时区,可以调整日期字符串或者用Date的其他构造方式。
情况B:ts是秒级时间戳(数字)
需要把Date对象的毫秒时间值转成秒,记得取整(避免小数问题):
// 用Math.floor取整,确保是整数秒级时间戳 db.my_collection.find({"ts": {$lt: Math.floor(new Date("2020-12-09").getTime() / 1000)}})
这种方式的好处是能利用ts字段上的索引,查询效率很高。
2. 复杂场景:用$expr结合聚合操作符
如果你需要更复杂的日期转换逻辑(比如动态计算日期),可以用$expr来在查询中使用聚合表达式,这样就能用$toLong这类聚合操作符了:
秒级ts的情况
db.my_collection.find({ $expr: { // 将Date转成毫秒后除以1000得到秒级时间戳,再和ts对比 $lt: ["$ts", {$divide: [{$toLong: new Date("2020-12-09")}, 1000]}] } })
毫秒级ts的情况
db.my_collection.find({ $expr: { // 直接用$toLong把Date转成毫秒级时间戳,和ts对比 $lt: ["$ts", {$toLong: new Date("2020-12-09")}] } })
注意:使用$expr的查询可能无法利用ts字段上的索引,所以如果你的集合数据量很大,优先考虑第一种方案。
为什么你的原语句会返回空?
你原来的写法{"ts": {$lt: {$toLong : new Date("2020-12-09")}}}中,MongoDB会把{$toLong : new Date("2020-12-09")}当成一个普通的键值对文档,而你的ts是数字类型,两者完全不匹配,所以查询结果为空。
内容的提问来源于stack exchange,提问作者roschach
相关产品推荐
相关产品推荐

