MongoDB 像分面搜索这样的聚合

MongoDB aggregation like faceted search

以集合为例:

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"}]}
])

如果必须聚合字典列表并获取每个字典的分组计数,如下所示:

(品牌)
品牌 1 : 2
品牌 2 : 1
品牌 3:2

(颜色)
颜色 1 : 2
颜色 2 : 2
颜色 3 : 3

获得此信息的相关方法是什么?

您必须unwind your data to get a flat dataset and than group过滤值。

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
}

按如下方式使用此聚合:

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