2015-04-01 37 views
3

我在MongoDB中以下客戶訂單數據

"_id" : 7, 
"customer name" : "John Smith", 
"OrderItem" : [ 
     { 
       "product_category" : "Mobile", 
       "price" : 900 
     }, 
     { 
       "product_category" : "Computer", 
       "price" : 4200.48 
     }, 
     { 
       "product_category" : "TV", 
       "price" : 670.20 
     }, 
     { 
       "product_category" : "TV", 
       "price" : 960.52 
     } 
] 

我需要平均每個產品類別是這樣的:

"_id" : 7, 
"customer name" : "John Smith", 
"OrderItem" : [ 
     { 
       "product_category" : "Mobile", 
       "price" : 900 
     }, 
     { 
       "product_category" : "Computer", 
       "price" : 4200.48 
     }, 
     { 
       "product_category" : "TV", 
       "price" : 815.36 
     } 
] 

我試着使用$展開,但不知道如何分組。任何幫助?

+4

你究竟如何嘗試? – 2015-04-01 09:41:41

+3

'product_category'或'product_name'? – Yogesh 2015-04-01 09:44:47

回答

1

使用aggregation framework用一條管道將它由以下幾個階段組成:$match操作中,第一流水線級過濾文檔流只允許匹配的文檔(文檔,在你的情況_id = 7)來傳遞未修改到下一個管道階段,這是$unwind操作。這將從輸入文檔中分解所需的OrderItem數組字段,以便爲每個元素輸出一個文檔,然後您可以對其進行分組,並執行聚合操作以查找類別價格的平均值。流水線中的下一個階段是$ group操作,然後將輸入文檔分組product_category,並將$avg表達式應用於price上的每個組。最後階段$project然後重新整形流中的每個文檔以產生期望的結果。因此,你的聚集看起來像:

db.collection.aggregate([ 
    { 
     "$match": {"_id": 7} 
    }, 
    { 
     "$unwind": "$OrderItem" 
    }, 
    { 
     "$group": { 
      "_id": "$OrderItem.product_category", 
      "average_price": { 
       "$avg": "$OrderItem.price" 
      } 
     } 
    }, 
    { 
     "$project": { 
      "_id": 0, 
      "product_category" : "$_id", 
      "average_price": 1 
     } 

    } 
]) 

結果

{ 
    "result" : [ 
     { 
      "average_price" : 4200.48, 
      "product_category" : "Computer" 
     }, 
     { 
      "average_price" : 815.36, 
      "product_category" : "TV" 
     }, 
     { 
      "average_price" : 900, 
      "product_category" : "Mobile" 
     } 
    ], 
    "ok" : 1 
} 
0

首先,你應該放鬆OrderItem然後將它們分組,並mongo $avg計算avarage。下面聚集將計算平均

db.collectionName.aggregate(
        {"$match":{"customer name":"John Smith"}}, // match specified customername 
        {"$unwind":"$OrderItem"}, // unwind the OrderItem 

        {"$group":{"_id":"$OrderItem.product_category", 
         "avg": {"$avg":"$OrderItem.price"} // mongo avg method used for avrage 
       }} 
      ).pretty() 

所以上面的查詢返回結果如下

{ "_id" : "Computer", "avg" : 4200.48 } 
{ "_id" : "TV", "avg" : 815.36 } 
{ "_id" : "Mobile", "avg" : 900 } 

但上述結果不匹配您給出預期的輸出,所以你應該組兩次獲得精確的輸出

 db.collectionName.aggregate(
       {"$match":{"customer name":"John Smith"}}, //match given criteria 
       {"$unwind":"$OrderItem"},   //unwind $OrderItem 

       {"$group":{"_id":"$OrderItem.product_category", 
          "customerName":{"$first":"$customer name"}, // group all data with calculating avg 
          "id":{"$first":"$_id"}, 
           "avg":{"$avg":"$OrderItem.price"}}}, 

        {"$group":{"_id":"$id", 
         "customer Name":{"$first":"$customerName"}, 
          "OrderItem":{"$push": {"product_category":"$_id","price":"$avg"}}}} // group them for expected output 

       ).pretty() 
0
.aggregate([ 
    {$unwind: "$OrderItem"}, 
    {$group: { 
     _id: {id: "$_id", cat: "$OrderItem.product_category"}, 
     name: {$first: "$customer name"}, 
     price: {$avg: "$OrderItem.price"} 
    }}, 
    {$group: { 
     _id: "$_id.id", 
     OrderItem: {$push: {product_category: "$_id.cat", price: "$price"}}, 
     "customer name": {$first: "$name"} 
    }} 
])