对于我的Rails+MongoId应用程序,我需要聚合数据以进行统计。我的模型正在呈现一个通用的 Web 应用程序,该应用程序has_many版本(又名:捆绑包)和相对用户激活:
App = {
"_id" : ObjectId("4ff2e2eab528571384000eb4"),
"name" : "my app",
"category_id": "4ff2e2eab528571384000cc0",
"bundles": [{
"_id" : ObjectId("4ff2e2eab528571384000dca"),
"activations" : [{
"user" : "user_0",
"_id" : ObjectId("4ff2e2eab528571384000dd0")
},
...
},
...
]
}
现在,我要做的就是返回每个应用程序CATEGORY_ID激活次数,alà:
results = [
{
"_id": "4ff2e2eab528571384000cc0",
"value": 243
},
...
]
我可以使用这个mapreduce函数轻松获得每个CATEGORY_ID的捆绑包总数:
map = function() {
for (var bundle in this.bundles) {
emit(this.category_id, 1);
}
};
reduce = function(key, values) {
var sum = 0;
values.forEach(function(value) {
sum += value;
});
return sum;
};
但是,当我尝试更深入地进入一个级别时,我根本没有获得任何结果:
map = function() {
for (var bundle in this.bundles) {
for (var activation in bundle.activations) {
emit(this.category_id, 1);
}
}
};
reduce = function(key, values) {
var sum = 0;
values.forEach(function(value) {
sum += value;
});
return sum;
};
任何想法都非常感谢。此致敬意
迈克·科斯塔
感谢您的提示 NOMOA,
我可以通过修改地图功能来解决我的问题,如下所示:
map = function() {
var len = this.bundles.length;
for (var i = 0; i < len; i++) {
if (this.bundles[i].activations !== undefined) {
emit(this.category_id, this.bundles[i].activations.length);
}
}
};
我不得不删除 for..在构造中支持更传统的 for..i++,添加一个"未定义"检查(如您所建议的),它运行良好(我也避免了双循环)!
此致敬意M. 科斯塔
您确定您的 map reduce 函数运行正确吗?
我想你应该检查捆绑激活是否为非空。在服务器日志中检查是否有任何错误。此外,通过服务器日志,您可以查看调试打印语句。