2016-03-04 168 views
0

我得到了以下型號貓鼬:貓鼬計算平均

var MobileAppSchema = mongoose.Schema({ 
    identifier: String, 
    ... 
}); 

var RecordingSchema = mongoose.Schema({ 
    ... , 
    app: { 
    type: mongoose.Schema.Types.ObjectId, 
    ref: 'MobileApp' 
    }, 
    length: Number, 
    ... 
}); 

現在,我得到MobileAppSchema的一些記錄,我想在那裏Recording.app等於我MobileApps的一個所有RecordingSchemas。對於所有獲取的文檔,我想獲得Recording.length的平均值。

我目前的做法,但我想直接聚合貓鼬查詢,而不是之後。

當前實現:

exports.averageTimeSpentForAppIdentifier = function(appIdentifier, done) { 
    mobileAppsForAppIdentifier(appIdentifier, function(err, mobileApps) { 
     if(err) { 
      return done(err); 
     } 

     var appIds = mobileApps.map(function(mobileApp) {return mobileApp._id;}); 

     Recording.find({ 
      'app': { $in: appIds}}, function(err, recordings) { 
      if(err) { 
       return done(err); 
      } 

      if(!recordings || recordings.length == 0) { 
       return done(null, 0); 
      } 

      var average = recordings 
      .map(function(recording,i,arr) { 
       return recording.length/arr.length 
      }) 
      .reduce(function(a,b) { 
       return a + b 
      }); 

      done(null, average); 
     }); 
    }); 
}; 
+2

而你的問題是什麼?因爲即使是天真的搜索,也能找到相當數量的結果來解釋如何計算mongodb中的聚集。 – Tomalak

回答

2

聚集框架是在您的處置在這裏。運行下面的管道將會給你想要的結果。它使用流水線作爲初始步驟來過濾掉進入聚合 流水線的文檔,該流水線沒有制定mobileApps ID的給定標準。

隨後的$group運營商的主要聚集即計算使用$avg蓄能器運營商的分組文件的平均長度:

exports.averageTimeSpentForAppIdentifier = function(appIdentifier, done) { 
    mobileAppsForAppIdentifier(appIdentifier, function(err, mobileApps) { 
     if(err) { 
      return done(err); 
     } 

     var appIds = mobileApps.map(function(mobileApp) {return mobileApp._id;}), 
      pipeline = [ 
       {"$match": { "app": { $in: appIds } } }, 
       { 
        "$group": { 
         "_id": null, 
         "average": { "$avg": "$length" } 
        } 
       } 
      ]; 

     Recording.aggregate(pipeline) 
       .exec(function (err, result){ 
        if(err) { 
         return done(err); 
        } 
        done(null, result[0].average); 
       }) 

     // Or using the fluent pipeline builder API   
     Recording.aggregate() 
       .match({ "app": { $in: appIds } }) 
       .group({ "_id": null, "average": { "$avg": "$length" }}) 
       .exec(function (err, result){ 
        if(err) { 
         return done(err); 
        } 
        done(null, result[0].average); 
       });  
    }); 
}; 
+1

非常感謝你,它像一個魅力。 – dehlen