【问题标题】:Trouble with mongo map reduce and aggregating key namesmongo map reduce和聚合键名的问题
【发布时间】:2011-11-23 22:42:47
【问题描述】:

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

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

每个对象都有一个或多个来源。

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

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

我的错误在哪里?

【问题讨论】:

    标签: mongodb mapreduce


    【解决方案1】:

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

    代替

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

    你需要:

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

    【讨论】:

    • 确实!我自己发现了这一点,但还没有来更新这个问题。我的回答如下:function red_s(key, values){ var total = 0; for (var i in values) { total += values[i]; } return total; }
    猜你喜欢
    • 1970-01-01
    • 2018-07-15
    • 2015-11-18
    • 2018-08-18
    • 2017-10-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多