我有一个类似的产品系列:
products = [
{
"ref": "1",
"facets": [
{
"type":"category",
"val":"kitchen"
},
{
"type":"category",
"val":"bedroom"
},
{
"type":"material",
"val":"wood"
}
]
},
{
"ref": "2",
"facets": [
{
"type":"category",
"val":"kitchen"
},
{
"type":"category",
"val":"livingroom"
},
{
"type":"material",
"val":"plastic"
}
]
}
]
我想选择和统计具有该类别的不同类别和产品数量(请注意,产品可以包含多个类别)。这样的事情:
[
{
"category": "kitchen",
"numberOfProducts": 2
},
{
"category": "bedroom",
"numberOfProducts": 1
},
{
"category": "livingroom",
"numberOfProducts": 1
}
]
如果我能为每个不同的facet类型得到相同的结果会更好,就像那样:
[
{
"facetType": "category",
"distinctValues":
[
{
"val": "kitchen",
"numberOfProducts": 2
},
{
"val": "livingroom",
"numberOfProducts": 1
},
{
"val": "bedroom",
"numberOfProducts": 1
}
]
},
{
"facetType": "material",
"distinctValues":
[
{
"val": "wood",
"numberOfProducts": 1
},
{
"val": "plastic",
"numberOfProducts": 1
}
]
}
]
我正在使用distinct,aggregate和mapReduce进行测试。但无法达到所需的效果。谁能告诉我好方法?
更新:
使用聚合,这可以为我提供产品具有的不同方面类别,但不包括值和不同值的计数:
db.products.aggregate([
{$match:{'content.facets.type':'category'}},
{$group:{ _id: '$content.facets.type'} }
]).pretty();
答案 0 :(得分:1)
以下聚合管道将为您提供所需的结果。在第一个管道步骤中,您需要对facets
数组执行$unwind
操作,以便对其进行解构以输出每个元素的文档。 $unwind
阶段之后是$group
个操作中的第一个,它按类别和类型对上一个流中的文档进行分组,并使用$ sum计算每个组中的产品数。然后,下一个管道阶段中的下一个$ group操作将使用$addToSet
运算符创建保存聚合值的数组。最后的管道阶段是$project
操作,然后通过修改现有字段来转换流中的文档:
var pipeline = [
{ "$unwind": "$facets" },
{
"$group": {
"_id": {
"facetType": "$facets.type",
"value": "$facets.val"
},
"count": { "$sum": 1 }
}
},
{
"$group": {
"_id": "$_id.facetType",
"distinctValues": {
"$addToSet": {
"val": "$_id.value",
"numberOfProducts": "$count"
}
}
}
},
{
"$project": {
"_id": 0,
"facetType": "$_id",
"distinctValues": 1
}
}
];
db.product.aggregate(pipeline);
<强>输出强>
/* 0 */
{
"result" : [
{
"distinctValues" : [
{
"val" : "kitchen",
"numberOfProducts" : 2
},
{
"val" : "bedroom",
"numberOfProducts" : 1
},
{
"val" : "livingroom",
"numberOfProducts" : 1
}
],
"facetType" : "category"
},
{
"distinctValues" : [
{
"val" : "wood",
"numberOfProducts" : 1
},
{
"val" : "plastic",
"numberOfProducts" : 1
}
],
"facetType" : "material"
}
],
"ok" : 1
}