Subhranath Chunder
Subhranath Chunder

Reputation: 533

MongoDB aggregation like faceted search

Taking the example of the collection like:

db.products.insert([
    {"product_name": "Product 1", "filters": [{"name": "brand", "value": "Brand 1"}, {"name": "color", "value": "Color 1"}]},
    {"product_name": "Product 2", "filters": [{"name": "brand", "value": "Brand 2"}, {"name": "color", "value": "Color 2"}]},
    {"product_name": "Product 3", "filters": [{"name": "brand", "value": "Brand 1"}, {"name": "color", "value": "Color 2"}]},
    {"product_name": "Product 4", "filters": [{"name": "brand", "value": "Brand 3"}, {"name": "color", "value": "Color 1"}]},
    {"product_name": "Product 5", "filters": [{"name": "brand", "value": "Brand 3"}, {"name": "color", "value": "Color 3"}]}
])

If one has to aggregate on list of dictionaries and get the grouped counts for each of them, like the following:

(brand)
Brand 1 : 2
Brand 2 : 1
Brand 3 : 2

(color)
Color 1 : 2
Color 2 : 2
Color 3 : 3

What might be the relevant way to get this?

Upvotes: 1

Views: 2639

Answers (2)

Neo-coder
Neo-coder

Reputation: 7840

Use this aggregation as below :

db.products.aggregate({
  "$unwind": "$filters"
}, {
  "$group": {
    "_id": {
      "value": "$filters.value",
      "name": "$filters.name"
    },
    "count": {
      "$sum": 1
    }
  }
}, {
  "$group": {
    "_id": "$_id.name",
    "data": {
      "$push": {
        "value": "$_id.value",
        "totalCount": "$count"
      }
    }
  }
}).pretty()

Upvotes: 3

take
take

Reputation: 2222

You have to unwind your data to get a flat dataset and than group by the filter values.

db.products.aggregate(
{
    $unwind: "$filters",
}, {
    $group: { 
        _id: "$filters.value",
        product_names: { $push: "$product_name" } ,
        count: { $sum: 1 }
    }
});

Returns

{
    "result" : [ 
        {
            "_id" : "Color 3",
            "product_names" : [ 
                "Product 5"
            ],
            "count" : 1
        }, 
        {
            "_id" : "Brand 3",
            "product_names" : [ 
                "Product 4", 
                "Product 5"
            ],
            "count" : 2
        }, 
        {
            "_id" : "Color 2",
            "product_names" : [ 
                "Product 2", 
                "Product 3"
            ],
            "count" : 2
        }, 
        {
            "_id" : "Color 1",
            "product_names" : [ 
                "Product 1", 
                "Product 4"
            ],
            "count" : 2
        }, 
        {
            "_id" : "Brand 2",
            "product_names" : [ 
                "Product 2"
            ],
            "count" : 1
        }, 
        {
            "_id" : "Brand 1",
            "product_names" : [ 
                "Product 1", 
                "Product 3"
            ],
            "count" : 2
        }
    ],
    "ok" : 1
}

Upvotes: 1

Related Questions