Search code examples
mongodbgomgo

how to use $facet in golang with library mgo?


I started learning performance improvements on mongoDb. And i have a question based aggregation functions. I have created a basic test collection with 3 fields product, colour and year:

{
    "product" : "car",
    "colour" : "red",
    "year" : "2019"
}
{
    "product" : "car",
    "colour" : "black",
    "year" : "2018"
}
{
    "product" : "bike",
    "colour" : "blue",
    "year" : "2014"
}
{
    "product" : "train",
    "colour" : "black",
    "year" : "2019"
}
{
    "product" : "ship",
    "colour" : "red",
    "year" : "2018"
}
{
    "product" : "car",
    "colour" : "red",
    "year" : "2016"
}
{
    "product" : "car",
    "colour" : "blue",
    "year" : "2015"
}
{
    "product" : "bike",
    "colour" : "white",
    "year" : "2014"
}
{
    "product" : "train",
    "colour" : "red",
    "year" : "2016"
}
{
    "product" : "ship",
    "colour" : "red",
    "year" : "2015"
}

Due to performance issue, i wish to use facet for single aggregation stage:

 db.getCollection('test').aggregate([
    {
        "$match":{
            "colour":"red"
        }
    },
    {
        "$facet": {
            "cntOfReds":[
                {"$group":{"_id": "$product", "count": {"$sum": 1}}}
            ],
            "cntOfRedsIn2015":[
                {"$match" :{"year": "2015"}},
                {"$group": {"_id": "$year", "count": {"$sum": 1}}}
            ]
    }   }

    ])

How do we implement the same query on golang with mgo.v2 and set the results to a struct?


Solution

  • Using mgo, you have to pass an array of documents to Pipe:

    p:=collection.Pipe([]bson.M{
      {"$match": bson.M{"colour":"red"}},
      {"$facet": bson.M{ "cntOfReds":[]bson.M{{"$group":{"_id": "$product", "count": bson.M{"$sum":1}}}}},
      "cntOfRedsIn2015": ...
    

    Then, run the pipeline and get results:

    p.All(&results)