Search code examples
mongodbfacetfaceted-search

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?


Solution

  • 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()