使用mongo-driver/mongo通过表达式作为键值对的值查询文档
解决MongoDB Go驱动查询中时间条件的问题
你的问题出在把MongoDB的查询操作符写成了字符串,驱动会把整个字符串当作date字段的匹配值,自然查不到符合条件的文档。下面是两种正确的实现方式:
方式一:在Go端计算目标时间(推荐)
这种方式性能更好,因为可以利用date字段的索引,不需要MongoDB服务器额外计算:
import ( "context" "time" "go.mongodb.org/mongo-driver/bson" ) // 计算当前时间往前推100天的时间点 oneHundredDaysAgo := time.Now().AddDate(0, 0, -100) // 构造正确的查询条件 filter := bson.D{ {"date", bson.D{{"$gte", oneHundredDaysAgo}}}, {"enabled", true}, } cursor, err := collection.Find(context.TODO(), filter)
方式二:使用MongoDB服务器端表达式(不推荐,除非必要)
如果必须在MongoDB端计算时间,可以用$expr组合操作符,但这种方式无法利用索引,性能较差:
import ( "context" "go.mongodb.org/mongo-driver/bson" ) filter := bson.D{ {"$expr", bson.D{ {"$gte", bson.A{ "$date", bson.D{{"$subtract", bson.A{ bson.D{{"$currentDate", "timestamp"}}, 100 * 24 * 60 * 60 * 1000, // 100天的毫秒数 }}}, }}, }}, {"enabled", true}, } cursor, err := collection.Find(context.TODO(), filter)
为什么原代码不生效?
你原代码中把"$gte: new Date((new Date().getTime() - (1000*60*60*24*100)))"作为字符串值传给date键,MongoDB会尝试匹配date字段等于这个字符串的文档,而不是解析成时间范围条件,所以返回0条结果。正确的操作符格式是用嵌套的bson.D结构,将$gte作为子键,对应的值为时间条件。
内容的提问来源于stack exchange,提问作者Foobar
相关产品推荐
相关产品推荐

