2015-04-23 52 views
1

我有一个产品集合,看起来像:MongoDB的选择不同和计数

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

它会更好,如果我能得到相同的结果对每个不同的面型,这样的事情:

[ 
    { 
    "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 
      } 
      ] 
    } 
]  

我做具有鲜明,聚集和MapReduce测试。但无法达到所需的结果。任何人都可以告诉我好方法吗?

UPDATE:

与骨料,这给我的产品有不同的面类,而不是值也不值不同的计数:

db.products.aggregate([ 
    {$match:{'content.facets.type':'category'}}, 
    {$group:{ _id: '$content.facets.type'} } 
]).pretty(); 
+0

向我们展示具有鲜明,聚集和MapReduce你的测试。 –

回答

0

下聚合管道会给你期望的结果。在第一个流水线步骤中,您需要对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 
} 
+1

太好了,谢谢!让我试试真正的数据库,我会尝试了解管道... – wildbyte