MapReduce与MongoDB - 减少运行的次数?

时间:2012-06-20 13:59:50

标签: mongodb mapreduce

我在MongoDB中使用MapReduce,我想我已经把所有这些都包围了,除了一件我还不明白的事情:reduce运行了多少次?

例如,我有一个“项目”集合,每个项目都有一个“类别”。这是测试数据(用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;
};

(输出结构在map中与reduce中的相同,因为它需要。)

所以我用verbose=true通过mapReduce运行它,它显示了这些统计信息:

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

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

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

谢谢!

2 个答案:

答案 0 :(得分:4)

是的,你是正确的,如果只发出一次密钥,则不会运行reduce。我不认为存在能够告诉你减少多少次运行的数学公式。

答案 1 :(得分:1)

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