MongoDB MapReduce,reduce函数的第二个参数是多维数组

时间:2014-06-18 10:43:56

标签: mongodb multidimensional-array mapreduce

我尝试将mapReduce用于我的收藏。仅用于调试我返回vals值作为第二个参数传递reduce函数,如下所示:

db.runCommand({
 "mapreduce":"MyCollection",
 "map":function() {
    emit( {
       country_code:this.cc,
       partner:this.di,
       registeredPeriod:Math.floor((this.ca - 1399240800)/604800)
    },
    {
       count:Math.ceil((this.lla - this.ca)/86400)
    });
 },
 "reduce":function(k, vals) {
    return {
       'count':vals
    }; 
 },
 "query":{
    "ca":{
       "$gte":1399240800
    },
    "di":405,
    "cc":"1"
 },
 "out":{
    "inline":true
 }
});

我得到了这样的结果:

{
"results" : [
    {
        "_id" : {
            "country_code" : "1",
            "distribution" : 405,
            "installationPeriod" : 0
        },
        "value" : {
            "count" : [
                {
                    "count" : 37
                },
                {
                    "count" : 38
                }
            ]
        }
    },
    {
        "_id" : {
            "country_code" : "1",
            "distribution" : 405,
            "installationPeriod" : 1
        },
        "value" : {
            "count" : 36
        }
    },
    {
        "_id" : {
            "country_code" : "1",
            "distribution" : 405,
            "installationPeriod" : 4
        },
        "value" : {
            "count" : [
                {
                    "count" : [
                        {
                            "count" : 16
                        },
                        {
                            "count" : 16
                        }
                    ]
                },
                {
                    "count" : 15
                }
            ]
        }
    }
],
"timeMillis" : 38,
"counts" : {
    "input" : 130,
    "emit" : 130,
    "reduce" : 5,
    "output" : 6
},
"ok" : 1
}

我真的不知道为什么我将多维数组作为reduce函数的第二个参数。我的意思是这部分结果:

        {
        "_id" : {
            "country_code" : "1",
            "distribution" : 405,
            "installationPeriod" : 4
        },
        "value" : {
            "count" : [
                {
                    "count" : [ // <= Why is this multidimensional?
                        {
                            "count" : 16
                        }

为什么这是多维的?为什么嵌入式数组的键与reduce函数返回的相同?

1 个答案:

答案 0 :(得分:1)

原因是因为这是mapReduce的工作原理。来自documentation point

  

MongoDB可以为同一个密钥多次调用reduce函数。在这种情况下,该键的reduce函数的先前输出将成为该键的下一个reduce函数调用的输入值之一。

稍后一点:

  

返回对象的类型必须与map函数发出的值的类型相同,以确保以下操作为真:

因此,即使您没有像文档所指出的那样“更改签名”,您仍然只在一个reduce pass中一次处理n项,然后在下一个pass中再处理n个项目。在最终处理时会发生什么,一个片段中返回的数组与另一个片段中的数组合并。

所以发生了什么是你的reduce返回一个数组,但它不是你为密钥发出的“全部”项目,只是其中一些。然后另一个减少相同的“关键”处理更多的项目。最后,这两个数组(或可能更多)再次被发送到reduce,以试图实际“减少”这些项目。

这是一般概念,因此当您只是推回阵列时,这就不足为奇了。

简短版本,mapReduce处理块中的输出“键”而不是一次性处理。现在,在它成为你之前的问题之前,最好先了解它。