2015-05-04 86 views
7

我們有一個聚合查詢投影幾個子文檔。我們希望對這些計劃值應用一些算術運算,如Sum和Product。用於算術運算的MongoDB聚合 - 子文檔字段

聚集查詢 -

Item.aggregate([ 
     { $unwind: '$dummy'},  
     { $match: {'dummy.storage': {$gt: 0}} }, 
     { $group: {_id: '$_id', 
        dummy: {$push: '$dummy'}, 
        original_y: { $first: "$original_y" }, 
        new_y: { $first: "$new_y" }, 

     }}, 
     {$project:{ 
        original_y: 1, new_y: 1, 
        tallyAmount: {$sum: ["$new_y","$original_y"] } 
       } 
     }, 
    ] 
    ) 
    .exec(function(err, results){ 
     if(err) 
     { 
      console.log("Error : " + err); 
      return res.json ({error: "Error"}); 

     } 
     else if(!(results) || results == null || results.length == 0) 
     { 
      console.log("No Results Found"); 
      return res.json ({error: "No Results Today"}); 

     }else{ 

      res.send(results); 
     } 
    }); 

這給出了一個錯誤,說明 invalid operator '$sum'

我們應該做些什麼來獲得original_ynew_y$project總和?

EDIT

文件:

{ 
id:1, 
original_y: 200, 
new_y: 140, 
dummy: [ 
    {id:1, storage:2, cost: 10}, 
    {id:2, storage:0, cost: 20}, 
    {id:3, storage:5, cost: 30}, 
    ] 
} 

產出預期:

{ 
    id:1, 
    original_y: 200, 
    new_y: 140, 
    dummy: [ 
     {id:1, storage:2, cost: 10, tallyAmount: 34}, 
     {id:3, storage:5, cost: 30, tallyAmount: 11.33}, 
     ] 
    } 

其中, tallyAmount = (original_y + new_y)/cost

ERROR:不能用於子添加表達式因爲已經有一個表達式適用於整個字段

+0

@chridam已更新文檔和預期輸出 –

+0

感謝您的更新,我已在下面更新了我的答案以包含更改。 – chridam

回答

5

沒有關於文檔模式和預期聚合結果的更多細節,我建議您嘗試以下聚合,因爲我相信您需要運算符$add而不是$sum運營商。請注意,$sum運營商僅適用於$group運營商。隨着$add運營商,這兩個數字/場加在一起,並將結果保存在一個新的領域與$project操作:

Item.aggregate([ 
    { "$match": { "dummy.storage": { "$gt": 0 } } }, 
    { "$unwind": "$dummy" }, 
    { "$group": { 
     "_id": "$_id", 
     "original_y": { "$first": "$original_y" }, 
     "new_y": { "$first": "$new_y" } 
    } }, 
    { "$project": { 
     "original_y": 1, 
     "new_y": 1, 
     "tallyAmount": { "$add": [ "$new_y", "$original_y" ] } 
    } } 
]).exec(callback); 

- UPDATE -

滿足條件tallyAmount = (original_y + new_y)/cost ,你應該在你的$項目的作業流水線階段使用$add$divide算術運算符從而最終聚合管道應該是這樣的:

Item.aggregate([ 
    { "$match": { "dummy.storage": { "$gt": 0 } } }, 
    { "$unwind": "$dummy" }, 
    { 
     "$project": { 
      "original_y": 1, 
      "new_y": 1, 
      "dummy.id": "$dummy.id", 
      "dummy.storage": "$dummy.storage", 
      "dummy.cost": "$dummy.cost", 
      "dummy.tallyAmount": { 
       "$divide": [ 
        { "$add": ["$new_y","$original_y"] }, 
        "$dummy.cost" 
       ] 
      } 
     } 
    }, 
    { 
     "$group": { 
      "_id": "_$id", 
      "original_y": { "$first": "$original_y" }, 
      "new_y": { "$first": "$new_y" }, 
      "dummy": { 
       "$addToSet": "$dummy" 
      } 
     }   
    } 
]).exec(callback); 
+1

唯一的問題是,'tallyAmount'字段需要位於每個'虛擬'子文檔中。我面臨着以前從未聽說過的錯誤! '錯誤:無法爲虛擬子字段添加表達式,因爲已經有一個適用於整個字段的表達式' –

+0

@RohitLala好吧,我用正確的聚合管道更新了我的答案,考慮了期望輸出。 – chridam

+1

像寶石一樣工作! :d –