2012-06-20 126 views
2

我在MongoDB中使用MapReduce,我想我已经把所有的东西都包裹起来了,除了一块我还不明白:reduce运行多少次?MapReduce与MongoDB - 多少次减少运行?

例如,我有一个“项目”的集合,每个都有一个“类别”。这是测试数据(JavaScript编写,对于一个的node.js单元测试):

var i = 0; 
var dummyCategories = [ 
    { categoryId:(++i), categoryName:'Category '+i }, // [0] 1 
    { categoryId:(++i), categoryName:'Category '+i }, // [1] 2 
    { categoryId:(++i), categoryName:'Category '+i }, // [2] 3 
    { categoryId:(++i), categoryName:'Category '+i }, // [3] 4 
    { categoryId:(++i), categoryName:'Category '+i } // [4] 5 
]; 

i=0; 
var dummyItems = [ 
    { itemId: 'TestItem' + (++i), title: 'Test Item ' + i,  // [0] 1 
    category: dummyCategories[0] 
    }, 
    { itemId: 'TestItem' + (++i), title: 'Test Item ' + i,  // [1] 2 
    category: dummyCategories[1] 
    }, 
    { itemId: 'TestItem' + (++i), title: 'Test Item ' + i,  // [2] 3 
    category: dummyCategories[2] 
    }, 
    { itemId: 'TestItem' + (++i), title: 'Test Item ' + i,  // [3] 4 
    category: dummyCategories[3] 
    }, 
    { itemId: 'TestItem' + (++i), title: 'Test Item ' + i,  // [4] 5 
    category: dummyCategories[4] 
    }, 
    { itemId: 'TestItem' + (++i), title: 'Test Item ' + i,  // [5] 6 
    category: dummyCategories[0] 
    } 
]; 

有6项,5类,出现两次的类别,其余一次之一。

在我的map函数中,我在发射(this.category.categoryId, { items: 1 });。 (这样做的完整版本包括除项目#值对象的其他指标,但这种行为是一样的两种方式。)

reduce功能如下:

function reduce(key, values) { 
    var totals = { 
    items: 0 
    }; 

    for (var i = 0; i < values.length; i++) { 
    totals.items += values[i].items; 
    } 

    return totals; 
}; 

(输出结构是在图中的相同减少,因为它需要)

所以我与verbose=true运行此通过MapReduce的,它显示了这些统计资料:

计数:{输出:5,发射:6,减少:1,输入:6}

输入:6有意义,有6个文件。 发射:6有意义,它每个文件发射1个类别。 输出:5有意义,有5个类别。 但为什么减少运行只有一次?

现在写出来,它似乎是运行减少每个出现的键不止一次。所以当一个密钥只发射一次时,它不会减少它。那是对的吗?确定减少运行次数的数学公式是什么?

谢谢!

回答

4

是的,你是正确的,减少不运行,如果钥匙只发出一次。我不认为有一个数学公式可以告诉你减少运行的次数。

1

只要有必要。对于大数据集,单个reduce调用将在节点之间分割并同时运行。个别减少的作业块的大小将根据配置而变化 - 文档说个人排放不能超过最大文档大小的一半 ,所以我认为这意味着最大减少批量将具有最大文档大小。