猫鼬计算平均
问题描述:
我得到了以下型号猫鼬:猫鼬计算平均
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);
});
});
};
答
聚集框架是在您的处置在这里。运行下面的管道将会给你想要的结果。它使用流水线作为初始步骤来过滤掉进入聚合 流水线的文档,该流水线没有制定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
而你的问题是什么?因为即使是天真的搜索,也能找到相当数量的结果来解释如何计算mongodb中的聚集。 – Tomalak