2014-05-13 88 views
0

,我有以下MongoDB的數據模型:MongoDB的嵌套分組

{ 
"_id" : ObjectId("53725814740fd6d2ee0ca2bb"), 
"date" : "2014-01-01", 
"establishmentId" : 1, 
"products" : [ 
    { 
     "productId" : 1, 
     "price" : 7.03, 
     "someOtherInfo" : 325, 
     "somethingElse" : 6878 
    }, 
    { 
     "productId" : 2, 
     "price" : 4.6, 
     "someOtherInfo" : 243, 
     "somethingElse" : 1757 
    }, 
    { 
     "productId" : 3, 
     "price" : 2.14, 
     "someOtherInfo" : 610, 
     "somethingElse" : 5435 
    }, 
    { 
     "productId" : 4, 
     "price" : 1.45, 
     "someOtherInfo" : 627, 
     "somethingElse" : 5762 
    }, 
    { 
     "productId" : 5, 
     "price" : 3.9, 
     "someOtherInfo" : 989, 
     "somethingElse" : 3752 
    } 
} 

什麼是讓所有機構的平均價格最快的方法?有沒有更好的數據模型來實現這一目標?

+0

我假設你是指平均每件產品的價格? (而不是所有的產品?)無論採用哪種方式,答案都是在產品陣列上使用$ unwind的聚合框架,而$ group使用$ avg運算符計算平均值。 –

回答

0

aggregation手術應該處理好這個。我建議看看$unwind操作。

東西沿着這些路線應該工作(只是爲例):

db.collection.aggregate(
    {$match: {<query parameters>}}, 
    {$unwind: "$products"}, 
    { 
    $group: { 
     _id: "<blank or field(s) to group by before averaging>", 
     $avg: "$price" 
    } 
    } 
); 

建在這種風格的集合應該產生有你想要的數據的JSON對象。

0

由於提供了更直接的答案在別的總語法錯誤是:

db.collection.aggregate([ 
    { "$unwind": "$products" }, 
    { "$group": { 
     "_id": null, 
     "avgprice": { "$avg": "$products.price" } 
    }} 
]) 

這裏aggregation framework的用法是先$unwind陣列,這是一種「去規範化」數組中的內容分解成單獨的文檔。

然後在你的null_id一個值傳遞$group階段,這意味着到$avg操作「組的一切」,並通過您的$products.price(注意點表示)在所有的返回的總平均值子集中的所有文檔中的子文檔條目。

查看full operator reference瞭解更多信息。

0

我發現最好的解決辦法是:

db.collection.aggregate([ 
    {$match:{date:{$gte:"2014-01-01",$lte:"2014-01-31"},establishmentId:{$in:[1,2,3,4,5,6]}} 
    { "$unwind": "$products" }, 
    { "$group": { 
     "_id": {date:"$date",product:"$products.productId"}, 
     "avgprice": { "$avg": "$products.price" } 
    }} 
]) 

而且東西我發現還在於它是更好的先用火柴,然後放鬆,以便有較少的項目,以放鬆身心。這導致更快的整體過程。