【问题标题】:mongodb map reduce value.countmongodb map减少value.count
【发布时间】:2011-09-27 09:09:24
【问题描述】:

在 mongodb 中,我有一个 map 函数如下:

var map = function() {
    emit( this.username, {count: 1, otherdata:otherdata} );
}

和reduce函数如下:

var reduce = function(key, values) { 
    values.forEach(function(value){
        total += value.count; //note this line
    }
    return {count: total, otherdata: values[0].otherdata}; //please ignore otherdata
}

问题在于指出的行:

total += value.count;

在我的数据集中,reduce 函数被调用了 9 次,假设的 map 缩减结果计数应该是 8908。

使用上面的行,返回的结果将正确返回为 8908。

但如果我将这一行改为:

total += 1;

返回的结果只有 909,大约是假设结果的 1/9。

另外我尝试了 print(value.count) 并且打印的结果是 1。

什么解释了这种行为?

【问题讨论】:

  • 你不需要在某处声明total吗?

标签: mongodb mapreduce


【解决方案1】:

简短回答:value.count 并不总是等于一。

长答案:这是 map reduce 的预期行为:reduce 函数正在聚合 map 函数的结果。但是,它确实通过产生中间结果(在您的情况下为小计)的小组汇总了地图功能的结果。然后在这些中间结果上再次运行 reduce 函数,因为它们是 map 函数的直接结果。以此类推,直到每个键只剩下一个中间结果,这就是最终结果。

可以看作是中间结果的金字塔:

发射(...)-| |- 减少-> | 发射(...)-| | | |- 减少->| 发射(...)-| | | | | | 发射(...)-|- 减少-> | | | |-> 减少 = 最终结果 发射(...)-| | | 发射(...)--- 减少 ------------ >| | 发射(...)-----------------减少 ->|

reduce 的数量及其输入是不可预测的,并且意味着保持隐藏。 这就是为什么你必须提供一个 reduce 函数,它返回与输入相同类型(相同模式)的数据。

【讨论】:

    【解决方案2】:

    reduce 函数不仅会在原始输入数据上调用,还会在其自己的输出上调用,直到有最终结果。所以它需要能够处理这些中间结果,例如从早期阶段出来的[{count: 5}, {count:3}, {count: 4}]。

    【讨论】:

      猜你喜欢
      • 2013-08-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多