2015-11-16 128 views
3

我有一個聚合函數,像這樣:

var match = {}; 
match["products.totalprice"] = {$exists:true}; 

var project = {}; 
    project["_id"] = 0 
    project["products.totalprice"] = 1; 
    project["line"] = "$products.closedate"; 

ThisCollection.aggregate([ 
    {$match: match}, 
    {$project: project}, 
    {$group: { 
     _id: "$line", 
     total: {$sum: {$ifNull: ["$products.totalprice", 0]}} 
    }} 

], function(err, docs){ 
    console.log(docs); 
}); 

我的模式實際上是與產品totalprice,closedate和其他一些領域嵌套陣列的名稱和_id領域:

db.data.save({name:"a",products:{totalprice:1,closedate:1,...}}) 
db.data.save({name:"b",products:{totalprice:2,closedate:2,...}}) 

和架構的樣子:

var Products = new Schema({ 
    totalprice: Number, 
    closedate: Date, 
    otherRandomFields: ... 
}) 

var ThisCollection = new Schema({ 
    name: String, 
    products:[Products] 
}); 

docs我s返回我期望看到的日期對象,但總數始終爲0.

我正在檢查$exists$ifNull,因爲我看到某處存在建議(但似乎現在無法找到)。我也確認products.totalprice在我的模式中是Number

任何事情都會跳出來,因爲不正確?

編輯

實際運行該功能(片)輸出:

0: {_id: ["2014-01-01T05:00:00.000Z"], total: 0} 
1: {_id: ["2014-01-31T05:00:00.000Z"], total: 0} 
2: {_id: ["2014-02-01T05:00:00.000Z"], total: 0} 

是很奇怪,_id返回一個數組?

更多信息

想這可能已經與$sum一個問題,所以嘗試了一些其他的方法,如$first$push - 這裏是從$push輸出:

0: {_id: "2014-01-01T05:00:00.000Z", total: [0, 0, 0, 0, 0, 0, 0, 0, 0, 0]} 
1: {_id: "2014-01-31T05:00:00.000Z", total: [0, 0, 0]} 
2: {_id: "2014-02-01T05:00:00.000Z", total: [0, 0, 0, 0, 0, 0, 0]} 
+0

如果您可以編輯您的問題以包含一些示例文檔和聚合的預期輸出,那將非常有用。 – chridam

+0

@chridam我添加了一些細節。我有成千上萬的實際文件存儲。我期望將_id作爲'products.closedate'被聚合,'total'應該是來自每個'products.closedate'的'products.totalprice'的總和。 –

+0

@chridam我得到'_id'字段作爲'products.closedate'正如所料,但相應的'total'字段總是返回'0' –

回答

1

嘗試以下聚合管道它提取了$year,$month,$dayOfMonth從您的日期,然後使用這些作爲按鍵組。另外,如果該字段存在檢查和分配一個值的邏輯最好應在$project管道做,因爲這可讓您方便地調試流水線操作和代碼是可讀的:

var match = {}; 
match["products.totalprice"] = {$exists:true}; 

var project = {}; 
    project["_id"] = 0;   
    project["line"] = { 
     "year": { "$year": "$products.closedate" }, 
     "month": { "$month": "$products.closedate" }, 
     "day": { "$dayOfMonth": "$products.closedate" } 
    }; 
    project["total"] = { 
     "$ifNull": [ "$products.totalprice", 0 ] 
    } 

ThisCollection.aggregate([ 
    {$unwind: "$products"}, 
    {$match: match}, 
    {$project: project}, 
    {$group: { 
     _id: "$line", 
     total: { $sum: "$total" } 
    }} 

], function(err, docs){ 
    console.log(docs); 
}); 

的是$unwind屬性,否則它試圖將由$total返回的數組相加在一起。

+1

'project [「line」]'語句似乎不起作用(doc返回'undefined'),但沒有這個,totalpriceExists似乎正在工作。做一些測試...... –

+0

這是返回按日期匹配的記錄總數,但不是實際總價格字段的總和。 –

+1

我更新了你的答案。這適用於除年/月/日字段之外的羣組。這不是OP的一部分,**但是**我真的想讓這部分工作,這是非常有用的。 –