猫鼬计算平均

问题描述:

我得到了以下型号猫鼬:猫鼬计算平均

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

聚集框架是在您的处置在这里。运行下面的管道将会给你想要的结果。它使用流水线作为初始步骤来过滤掉进入聚合 流水线的文档,该流水线没有制定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