Mr.D
Mr.D

Reputation: 7873

Mongoid, aggregate models by name and number

I have model named Shop which has name, image. There is possibility that there will be multiple shops with the same name.

For example if I have these shops:

 [{_id: "1", name: "Shop A", image: "ImageShopA.jpg"},
  {_id: "2", name: "Shop A", image: "ImageShopA1.jpg"},
  {_id: "3", name: "Shop B", image: "ImageShopB.jpg"},
  {_id: "4", name: "Shop B", image: "ImageShopB1.jpg"},
  {_id: "5", name: "Shop C", image: "ImageShopC.jpg"}]

I want to get this kind of result:

 [{name: "Shop A", ids: ["1", "2"], image: "ImageShopA.jpg"}, 
  {name: "Shop B", ids: ["3", "4"], image: "ImageShopB.jpg"},
  {name: "Shop C", ids: ["5"], image: "ImageShopC.jpg"}]

It creates JSON Objects which has ids of grouped models which are grouped by name and get image of first found model.

Is it possible to do that with aggregation?

Upvotes: 1

Views: 59

Answers (1)

chridam
chridam

Reputation: 103365

Yes, its possible. If you run the following aggregation pipeline in mongo shell with the given data sample

db.collection.aggregate([
    {
        "$sort": {
            "_id": 1
        }
    },
    {
        "$group": {
            "_id": "$name",
            "ids": {
                "$push": "$_id"
            },
            "image": {
                "$first": "$image"
            }
        }
    },
    {
        "$project": {
            "name": "$_id", "ids": 1, "image": 1
        }
    }
])

you will get the desired results:

/* 0 */
{
    "result" : [ 
        {
            "_id" : "Shop C",
            "ids" : [ 
                "5"
            ],
            "image" : "ImageShopC.jpg",
            "name" : "Shop C"
        }, 
        {
            "_id" : "Shop B",
            "ids" : [ 
                "3", 
                "4"
            ],
            "image" : "ImageShopB.jpg",
            "name" : "Shop B"
        }, 
        {
            "_id" : "Shop A",
            "ids" : [ 
                "1", 
                "2"
            ],
            "image" : "ImageShopA.jpg",
            "name" : "Shop A"
        }
    ],
    "ok" : 1
}

You would need to convert this to the appropriate ruby implemenation

Upvotes: 1

Related Questions