MongoDB实现类似MySQL的updated_at+refresh_interval<now()查询
MongoDB实现类似MySQL的时间运算查询
嘿,这个转换其实不难,我来给你拆解清楚!你要实现的MySQL查询逻辑是找出updated_at加上refresh_interval秒后早于当前时间的所有条目,对应到MongoDB里,我们可以借助聚合表达式来搞定,具体分两种常用的写法:
1. 使用find查询(MongoDB 4.0+)
如果你用的是4.0及以上版本的MongoDB,可以直接在find里用$expr来实现字段间的运算比较,写法如下:
db.items.find({ $expr: { $lt: [ // 将updated_at(BSON日期)加上refresh_interval转成的毫秒数 { $add: ["$updated_at", { $multiply: ["$refresh_interval", 1000] }] }, // 当前时间 new Date() ] } })
2. 使用聚合管道(兼容所有支持聚合的版本)
如果你的MongoDB版本较低,或者需要在聚合流程里做这个过滤,就用$match阶段来实现:
db.items.aggregate([ { $match: { $expr: { $lt: [ { $add: ["$updated_at", { $multiply: ["$refresh_interval", 1000] }] }, // 聚合里推荐用$$NOW表示服务器当前时间 "$$NOW" ] } } } ])
关键细节解释
- 为什么要乘以1000?:因为
refresh_interval存储的是秒数,而MongoDB的BSON日期是以毫秒为单位存储的,必须把秒转成毫秒才能和updated_at的时间值正确相加,否则会出现时间计算错误。 $expr的作用:普通的find查询条件只能做字段和固定值的比较,无法实现字段之间的运算,$expr允许我们在查询条件中使用聚合表达式,这样就能完成updated_at和refresh_interval的组合运算了。new Date()vs$$NOW:两者都代表当前时间,new Date()是客户端时间,$$NOW是MongoDB服务器的时间,在聚合场景下更推荐用$$NOW来保证时间一致性。
举个实际例子验证:假设你有这样一个文档:
{ _id: 1, updated_at: ISODate("2024-05-01T10:00:00Z"), refresh_interval: 3600 // 1小时,即3600秒 }
如果当前时间是2024-05-01T12:00:00Z,那么updated_at + 3600秒的结果是2024-05-01T11:00:00Z,早于当前时间,这个文档会被成功匹配到。
内容的提问来源于stack exchange,提问作者Hlorofos
相关产品推荐
相关产品推荐

