2015-04-23 102 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