关于深层嵌套文档问题的MongoDB MapReduce问题

时间:2012-07-03 13:47:14

标签: mongodb mapreduce mongoid

对于我的Rails + MongoId应用程序,我需要汇总数据以用于统计目的。 我的模型是一个普通的Web应用程序,它具有多个版本(又名:bundle)和相对用户激活:

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的BUNDLES总数:

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;
};

非常感谢任何想法。最好的问候

迈克·科斯塔

2 个答案:

答案 0 :(得分:1)

感谢提示NOMOA,

我可以通过修改map函数来解决我的问题,如下所示:

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..in contruct以支持更传统的for..i ++,添加一个“undefined”检查(正如你的建议)并且它完美运行(我也避免了双循环)!

祝你好运 M. Costa

答案 1 :(得分:0)

您确定地图缩小功能是否正确运行?

我猜你应该检查bundle.activations是否为非null。 检查服务器日志中是否有任何错误。 此外,使用服务器日志,您可以查看调试打印语句。