user5766400
user5766400

Reputation:

Aggregation With Golang/Mongodb Gives Error "Missing type in composite literal"

I am trying to get users in a certain age range via aggregation.

Edit: I am able to work through mongo shell, query works fine however I am not able to make it work with go

This code gives me "missing type in composite literal" error.

What am I missing here?

lte := 10
gte := 0

operations := []bson.M{
    {
        "$match":{
            "$and":[]interface{}{
                bson.M{"age":{"$gte":gte}},
                bson.M{"age":{"$lte":lte}},
            },
        },
    },
    {
        "$group":bson.M{"_id":"$user_id"},
    },

}

r := []bson.M{}

pipe := c.Pipe(operations)
err := pipe.All(&r)
if err != nil {
    logrus.Errorf("Error:  %v", err)
    return err
}

Upvotes: 2

Views: 1142

Answers (2)

user161778
user161778

Reputation: 534

I believe this is what you want:

operations := []bson.M{
    bson.M{
        "$match":bson.M{
            "$and":[]interface{}{
                bson.M{"age":bson.M{"$gte":gte}},
                bson.M{"age":bson.M{"$lte":lte}},
            },
        },
    },
    bson.M{
        "$group":bson.M{"_id":"$user_id"},
    },

}

You simply forgot bson.M before "$and".

Edit: Looks like the ages too, I went ahead and fixed those.

Edit2: I missed more bson.M's than the initial 3 missing that I saw.

Upvotes: -1

Blakes Seven
Blakes Seven

Reputation: 50406

You have not defined "each" pipeline stage as a bson.M. It's an "array" of bson.M, hence the error:

operations := []bson.M{
    bson.M{
        "$match": bson.M{
            "date": bson.M{ "$gte": gte, "$lte": lte }
        }
    },
    bson.M{
        "group": bson.M{ "_id": "$user_id" }
    }
}

Also $and is not necessary. ALL MongoDB query conditions are already an "AND" expression anyway. The combination of $gte and $lte as keys in the same object expression is already an AND condtion on the same "date" property. Just as would be the addition of more keys within the $match object.

In the JavaScript shell, this is the same as:

var operations = [
    { "$match": { "date": { "$gte": gte, "$lte": lte } } },
    { "$group": { "_id": "$user_id" } }
];

So you need to remember that every JavaScript object notation {} equals a .bson.M{} statement. That's how you notate BSON objects in go with this libary.

Note: { "$group": { "_id": "$user_id } } is not going to do anything meaningful other than just return each "distinct" "user_id" value. So you likely want more accumulator options in any real result

Upvotes: 3

Related Questions