Shahul H
Shahul H

Reputation: 11

How to aggregrate data created in the last hour in Go using MongoDB?

I want to aggregate the distance field created in the last hour.

The error I get is is: "missing type in composite literal"

My code:

var lastHour = time.Now()
var hour=lastHour.Hour()-1
pipeline := []bson.M{
    {"$match": bson.M{"createdAt":{"$gt":hour} }},
    {"$group":
    bson.M{"_id": "",
    "total distance": bson.M{ "$sum": "$distance" },
    "maximum distance": bson.M{ "$max": "$distance" },
    "minimum distance": bson.M{ "$min": "$distance" },
        },
    },

Upvotes: 1

Views: 287

Answers (1)

icza
icza

Reputation: 418117

First your error message

This composite literal is invalid:

[]bson.M{
    {"$match": bson.M{"createdAt":{"$gt":hour} }},
    ...

More specifically this part:

bson.M{"createdAt":{"$gt":hour} }

Because the bson.M type is:

type M map[string]interface{}

So a bson.M literal is effecively a map literal, where if the type of the value (in the key-value pairs) is not identical to the map type's value type, you have to explicitly write it out. This is mentioned in the spec:

Within a composite literal of array, slice, or map type T, elements or map keys that are themselves composite literals may elide the respective literal type if it is identical to the element or key type of T.

The key-value pair: "createdAt: {"$gt":hour}, the value here is another bson.M value, but you did not mention it. The value type of this map is interface{}, so the compiler cannot guess you want it to be another bson.M. You have to spell it out for the compiler.

The correct version is:

bson.M{"createdAt": bson.M{"$gt":hour}}

This fixes the compile-time error, but won't give you the desired result.

Now on to the task you want to achieve

If the createdAt field is a Date type in MongoDB, then pass a value of time.Time when filtering by it.

Regarding the value of the passed time.Time, calculate the time value 1 hour ago (from the current time). For that, you may use the time.Add() method, which adds a given time.Duration value to a time, and returns the new time. The duration may be negative to go back in time.

This is how it could look like:

anHourAgo := time.Now().Add(-time.Hour)
pipeline := []bson.M{
    {"$match": bson.M{"createdAt": bson.M{"$gt": anHourAgo}}},
    {"$group": bson.M{
        "_id":              "",
        "total distance":   bson.M{"$sum": "$distance"},
        "maximum distance": bson.M{"$max": "$distance"},
        "minimum distance": bson.M{"$min": "$distance"},
    }},
}

Upvotes: 1

Related Questions