How to filter date with golang and mongodb?

Viewed 9553

I'm trying to query records from mongodb using golang but seems like it's not working. I tried running the query with mongo cli using ISODate() and it works but I'm not sure how to call ISODate with golang. Below is a snippet of the code I'm running.

type Record struct{
    ID         primitive.ObjectID `bson:"_id"`
    PropertyID primitive.ObjectID `bson:"propertyID"`
    CreatedAt  primitive.DateTime `bson:"createdAt"`
}
// ....
cur, err := collection.Find(ctx, bson.M{"createdAt": bson.M{
    "$gte": time.Now().UTC().AddDate(-1, 0, 0).Format(time.RFC3339),
}})
// ....
var recs []Record
err = cur.All(ctx, &recs)

if I run len(recs) I get 0 but in mongo-cli I'm getting result when I run code below.

db.getCollection('records').find({
    createdAt: {
        $gte: ISODate("2019-11-02T23:16:58+08:00")
    }
}).sort({createdAt: -1})

by the way 2019-11-02T23:16:58+08:00 is the output of time.Now().UTC().AddDate(-1, 0, 0).Format(time.RFC3339)

Thanks in advance guys :D

3 Answers

Try primitive.NewObjectIDFromTimestamp.

From there you can convert time.Time to primitive.ObjectID and vice versa.

func NewObjectIDFromTimestamp(timestamp time.Time) ObjectID

NewObjectIDFromTimestamp generates a new ObjectID based on the given time.

Or primitive.NewDateTimeFromTime, what creates a DateTime.

func NewDateTimeFromTime(t time.Time) DateTime

NewDateTimeFromTime creates a new DateTime from a Time.

And then pass that to your query filter like this:

cur, err := collection.Find(ctx, bson.M{"createdAt": bson.M{
    "$gte": primitive.NewDateTimeFromTime(time.Now().AddDate(-1, 0, 0)),
}})

Since CreatedAt is of type primitive.Datetime, in your bson.M query on CreatedAt you need to pass primitive.Datetime object.

Golang's mongo driver handles marshaling for you.

cur, err := collection.Find(ctx, bson.M{"createdAt": bson.M{
    "$gte": primitive.NewDateTimeFromTime(time.Now())
}})

Here a simple sample using bson.D and aggregation:

import "go.mongodb.org/mongo-driver/bson/primitive"

    mongo.Pipeline{
            {{"$match", bson.D{
                {"createdAt", bson.D{
    {"$gt", primitive.NewDateTimeFromTime(time.Now().AddDate(0, 0, -30))}}}},
            }}}
    }
Related