Golang中使用MongoDB官方驱动按日期查询数据

Golang中使用MongoDB官方驱动按日期查询数据 大家好,我正在使用Golang的MongoDB官方驱动,请问如何执行日期范围的查询? 在shell中执行相同的查询能返回正确的结果,但使用mongo-db驱动执行相同的查询却返回空结果。

3 回复

问题已修复

更多关于Golang中使用MongoDB官方驱动按日期查询数据的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


请展示示例数据以及你的代码。你期望得到什么结果,实际又得到了什么?

在Golang中使用MongoDB官方驱动进行日期范围查询时,需要注意时区处理和BSON类型转换。以下是正确的实现方式:

package main

import (
    "context"
    "fmt"
    "time"
    
    "go.mongodb.org/mongo-driver/bson"
    "go.mongodb.org/mongo-driver/bson/primitive"
    "go.mongodb.org/mongo-driver/mongo"
    "go.mongodb.org/mongo-driver/mongo/options"
)

func main() {
    // 连接MongoDB
    client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI("mongodb://localhost:27017"))
    if err != nil {
        panic(err)
    }
    defer client.Disconnect(context.TODO())
    
    collection := client.Database("testdb").Collection("testcollection")
    
    // 定义日期范围(使用UTC时间避免时区问题)
    startDate := time.Date(2023, 1, 1, 0, 0, 0, 0, time.UTC)
    endDate := time.Date(2023, 12, 31, 23, 59, 59, 0, time.UTC)
    
    // 方法1:使用primitive.DateTime
    filter := bson.M{
        "created_at": bson.M{
            "$gte": primitive.NewDateTimeFromTime(startDate),
            "$lte": primitive.NewDateTimeFromTime(endDate),
        },
    }
    
    // 方法2:直接使用time.Time(驱动会自动转换)
    filter2 := bson.M{
        "created_at": bson.M{
            "$gte": startDate,
            "$lte": endDate,
        },
    }
    
    // 执行查询
    cursor, err := collection.Find(context.TODO(), filter)
    if err != nil {
        panic(err)
    }
    defer cursor.Close(context.TODO())
    
    // 处理结果
    var results []bson.M
    if err = cursor.All(context.TODO(), &results); err != nil {
        panic(err)
    }
    
    fmt.Printf("找到 %d 条记录\n", len(results))
}

如果查询返回空结果,常见问题及解决方案:

  1. 时区不一致:确保Go中的时间与MongoDB存储的时间使用相同的时区
// 检查存储的时间格式
var doc bson.M
collection.FindOne(context.TODO(), bson.M{}).Decode(&doc)
fmt.Printf("存储的时间: %v\n", doc["created_at"])
  1. 使用ISODate包装查询
filter := bson.M{
    "created_at": bson.M{
        "$gte": bson.M{"$date": startDate.Format(time.RFC3339)},
        "$lte": bson.M{"$date": endDate.Format(time.RFC3339)},
    },
}
  1. 处理ObjectID中的时间戳(如果使用ObjectID作为时间参考):
// 从ObjectID中提取时间范围
startObjectID := primitive.NewObjectIDFromTimestamp(startDate)
endObjectID := primitive.NewObjectIDFromTimestamp(endDate)

filter := bson.M{
    "_id": bson.M{
        "$gte": startObjectID,
        "$lte": endObjectID,
    },
}
  1. 调试查询:打印生成的BSON查看实际查询条件
fmt.Printf("查询条件: %+v\n", filter)

确保MongoDB中的日期字段存储为Date类型,而不是字符串类型,这是导致查询失败的最常见原因。

回到顶部