0

我有一個MongoDB的(貓鼬實體),它代表了我的應用程序金融項:兩個和一個查詢中

var mongoose = require('mongoose'); 
var ObjectId = mongoose.Schema.Types.ObjectId; 

var transactionSchema = mongoose.Schema({ 

    description  : String, 
    amount   : { type:Number, min:0.01, required:true }, 
    dateEntry  : { type:Date, default:Date.now }, 
    dateAdded  : { type:Date, default:Date.now }, 
    positive  : { type:Boolean, default:false }, 

    category  : { type: ObjectId, ref: 'Category' }, 
    user   : { type: ObjectId, ref: 'User' } 

}); 

module.exports = mongoose.model('Transaction', transactionSchema); 

我想給我的交易的平衡:我的第一種方法是使之和積極的條目,那麼負項的另一總和,最後減去從積極的消極之一:

async.parallel({ 
       totalPositive: function(callback) { 
        var matcher = baseSearch; 
        matcher.positive = true; 
        Transaction.aggregate(
         { $match: matcher }, 
         { $group: {_id:null,sum:{$sum: '$amount'}} }, 
         function(err,result) { 
          callback(err,result); 
         } 
        ); 
       }, 
       totalNegative: function(callback) { 
        var matcher = baseSearch; 
        matcher.positive = false; 
        Transaction.aggregate(
         { $match: matcher }, 
         { $group: {_id:null,sum:{$sum: '$amount'}} }, 
         function(err,result) { 
          callback(err,result); 
         } 
        ); 
       } 
      }, function(err, results) { 
       if (err) { 
        return res.json({error:err.message}); 
       } 
       results.balance = results.totalPositive[0].sum - results.totalNegative[0].sum; 
       res.json(results); 
      }); 

我不知道如果我可以有隻有一個返回的積極和消極之和保存一個查詢。

任何想法?或者這是最好的解決方案? 謝謝

回答

1

你可以這樣做是有條件的分組,然後就最後的項目做數學題:

Transaction.aggregate(
    [ 
     { "$group": { 
      "_id": null, 
      "totalPositive": { 
       "$cond": [ "$positive", "$amount", 0 ] 
      }, 
      "totalNegative": { 
       "$cond": [ "$positive", 0, "$amount" ] 
      } 
     }}, 
     { "$project": { 
      "totalBalance": { "$subtract": [ "$totalPositive", "$totalNegative" ] } 
     }} 
    ], 
    function(err,result) { 

    } 
) 

所以才評估是否$sum的「量」取決於什麼「積極」有爲true/false。然後在下面的流水線中使用$subtract運算符。

更重要的是,剛剛設置的值的「符號」,以在單個組級「和」:

Transaction.aggregate(
    [ 
     { "$group": { 
      "_id": null, 
      "totalBalance": { 
       "$sum": { 
        "$cond": [ 
         "$positive", 
         "$amount", 
         { "$subtract": [ 0, "$amount" ] } 
        ] 
       } 
     }} 
    ], 
    function(err,result) { 

    } 
); 

所以真的是沒有必要的並行查詢時,你可以做到這一點的一箇中風。

每種情況下的「肉」主要在這裏的$cond運營商,它作爲一個三元運營商進行評估。鏈接在那裏,但如果您不熟悉,那麼這意味着提供「內聯」評估的方式。所以有一個「test」作爲第一個參數,其中true第二個參數用於返回結果中,否則返回第三個參數false

有在SQL to aggregation mapping這給那些誰用於SQL,或至少用來解決問題的「聲明」語法幾種常見的實例文檔中提供的樣本等。建議

aggregation framework一般閱讀,因爲它本質上是在SQL方面differnce betweeen SELECT thisfield where anotherfield = "this"以先進的SQL每隔permuation相比基本.find()方法調用。

+0

聽起來不錯!我仍然是mongodb的初學者,非常感謝,我會盡力接受答案! – 2014-09-22 10:47:00

+1

@FabioB。很公平。慢慢來。我當時可能有點過於謹慎,並沒有提供足夠的聯繫或解釋。但是現在也添加了。 – 2014-09-22 11:06:41

+0

超好玩!我開始研究聚合框架。 – 2014-09-22 20:17:59