mongo map reduce和聚合键名的问题



我的数据库中有一个集合,表示从各种来源提取的IP地址。示例如下:

{ "_id" : ObjectId("4e71060444dce16174378b79"), "ip" : "xxx.xxx.xxx.xxx", "sources" : { "Source1" : NumberLong(52), "Source2" : NumberLong(7) } }

每个对象将有一个或多个源。

我的目标是显示每个源报告的条目数量,而不必知道每个可能源的名称(因为随时都可能添加新的源)。我试图通过简单地为每个对象的源散列中的每个键发出1来解决这个问题,但是我的语法似乎有些问题。如果我做以下操作:

var map_s = function(){
  for(var source in this.sources) {
    emit(source, 1);
  }
}
var red_s = function(key, values){
  var total = 0;
  values.forEach(function(){
    total++;
  });
  return total;
}
var op = db.addresses.mapReduce(map_s, red_s, {out: 'results'});
db.results.find().forEach(printjson);

{ "_id" : "Source1", "value" : 12 }
{ "_id" : "Source2", "value" : 230 }
{ "_id" : "Source3", "value" : 358 }
{ "_id" : "Source4", "value" : 398 }
{ "_id" : "Source5", "value" : 39 }
{ "_id" : "Source6", "value" : 420 }
{ "_id" : "Source7", "value" : 156 }

对于数据库的大小来说太小了。例如,如果我计算一个特定的源,我将在shell中得到以下内容:

> db.addresses.count({"sources.Source4": {$exists: true}});
1260538

我的错误在哪里?

是的,你的reduce方法有问题,它必须是幂等的。请记住,在中间结果上可能会多次调用reduce()。

不是

values.forEach(function(){
  total++;
});
你需要

:

values.forEach(function(x){
  total += x;
});

相关内容

  • 没有找到相关文章

最新更新