Search code examples
mongodbgofilteringmgo

Querying mongodb date between date range using golang mgo


I've tried following the solution mentioned here How can I query MongoDB with date range using mgo and Go? but I can't seem to get results for the dob range. "dob" in mongodb is stored as:

"dob": {
    "$date": "1967-06-28T00:00:00.000Z"
}

Without the dob query it works fine. I've tried switching $lt and $gt but still no luck. Does anyone know how to get this working? I've printed out dobLower and dobUpper and they both seem to be valid dates like 2000-06-28 21:57:06.666025643 +0000 UTC. The model for dob is Dob time.Time json:"dob" bson:"dob"

ageLower, err := strconv.Atoi(filters["ageLower"])
ageUpper, err := strconv.Atoi(filters["ageUpper"])
heightLower, err := strconv.Atoi(filters["heightLower"])
heightUpper, err := strconv.Atoi(filters["heightUpper"])
if err != nil {
    return nil, err
}

dobUpper := time.Now().AddDate(-ageLower, 0, 0)
dobLower := time.Now().AddDate(-ageUpper, 0, 0)

pColl := s.DB("mydb").C("profiles")

query := bson.M{
    "$and": []bson.M{
        bson.M{"active": bson.M{"$eq": true}},
        bson.M{"gender": bson.M{"$ne": u.Gender}},
        bson.M{"_id": bson.M{"$nin": u.HiddenProfiles}},
        bson.M{"_id": bson.M{"$ne": u.ProfileID}},
        bson.M{"dob": bson.M{"$gt": dobLower , "$lt": dobUpper}},
        bson.M{"height": bson.M{"$gt": heightLower, "$lt": heightUpper}},
    },
}

return pColl.Find(query).Select(bson.M{"first_name": 0}).All(&profiles)

Help will be much appreciated. Thanks.


Solution

  • If you store your dates as int64s you can use $lt etc with an integer comparison, but first you will have to add in a field of the date as an int64. To do this iterate over the collection and use time to convert the date from string to int64 by creating a time then getting the number of seconds from it. When adding new dates also save it as int64. Int comparisons will be quicker and if you index it the index would be smaller than a text one.

    iter := pColl.Find(nil).Iter()
    for iter.Next(&profile){
        t, _ := time.Parse(time.RFC3339, profile.DOB)
        x := t.Unix()
        theUpdate := bson.M{"$set": bson.M{"dobint": x}}
        pColl.UpdateId(profile.ID, theUpdate)
    }
    iter.Close()