MapReduce 上的Reduce 函数显示不正确的结果——为什么?

2024-02-24

我有一个数据结构来跟踪不同城市的人们:

//in db.persons
{
  name: "John",
  city: "Seattle
},
{
  name: "Bill",
  city: "Portland"
}

我想运行一个地图缩减来获取每个城市有多少人的列表,所以结果将如下所示:

{
  _id: "Seattle",
  value: 10
}

我的地图缩减功能如下所示:

map = function(){
  var city = this.city
  emit(city, 1);
};


reduce = function(key, values){
    var result = 0;
    values.forEach(function(value){
      result += 1;
    });
    return result;
}

非常简单的东西,我想这需要city作为键,然后为找到的每个匹配城市的结果加一。然而,在生成的地图缩减中,该值相差很大。将我的归约函数切换为:

reduce = function(key, values){
    var result = 0;
    values.forEach(function(value){
      result += value;
    });
    return result;
}

并添加value到结果(应该是 1,据我所知,我的emit函数)返回了正确的结果。

为什么结果不同?难道我的value在reduce函数中是1吗?


发生这种情况是因为 MongoDB 可以对同一个键多次调用reduce 函数。这是一个简单的例子:

假设您的数据库中只有三个文档,每个文档都具有相同的“城市”“西雅图”。在发射阶段之后,您将拥有一组发射的对象,如下所示

{'Seattle' : 1}. {'Seattle' : 1}. {'Seattle' : 1}

发射阶段完成后,减少阶段开始。在最简单的情况下,reduce 函数将被调用为reduce('Seattle', [1,1,1])。在这种情况下,您的第一个函数将正常工作。但是,reduce 函数可能会被多次调用:

reduce('Seattle', [1,1]) -> {'Seattle' : 2}, {'Seattle', 1}

reduce('Seattle', [2,1])

在这种情况下,您的第一个归约函数将返回2在第二次reduce调用之后,因为值列表中有两项。在第二个归约函数中,您正确地将这些值加在一起,而不是仅仅对它们进行计数,这给出了正确的答案。

我个人认为CouchDB 文档 http://wiki.apache.org/couchdb/Introduction_to_CouchDB_views#Restrictions_on_map_and_reduce_functions更好地解释一下为什么您需要为其值数组输入使用可交换和关联的归约函数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

MapReduce 上的Reduce 函数显示不正确的结果——为什么? 的相关文章

随机推荐