MongoDB中MapReduce不一樣的寫法,不一樣的結果

MapReduce有兩種寫法,也能夠說mongodb全部的命令行都有兩種寫法。mongodb

但忽然間發現MapReduce不一樣的寫法會有不一樣的結果,接下來咱們一塊兒來看:函數

第一種:直接使用擴展屬性。

1)emit函數的第2參數直接使用數值。this

> db.entities.mapReduce(function(){emit(this.age,1)},function(key,value){var tot
al=0;for(var i in value){total+=value[i];} return total;},{query:{age:{"$gt":97}
},out:{inline:1}})
{
        "results" : [
                {
                        "_id" : 98,
                        "value" : 10602
                },
                {
                        "_id" : 99,
                        "value" : 11533
                }
        ],
        "timeMillis" : 414,
        "counts" : {
                "input" : 22135,
                "emit" : 22135,
                "reduce" : 223,
                "output" : 2
        },
        "ok" : 1,
}

看到results.value是正常值,方法可行。spa

2)emit函數的第2參數使用object對象。 命令行

> db.entities.mapReduce(function(){emit(this.age,{count:1})},function(key,value)
{var total=0;for(var i in value){total+=value[i].count;} return total;},{query:{
age:{"$gt":97}},out:{inline:1}})
{
        "results" : [
                {
                        "_id" : 98,
                        "value" : NaN
                },
                {
                        "_id" : 99,
                        "value" : NaN
                }
        ],
        "timeMillis" : 643,
        "counts" : {
                "input" : 22135,
                "emit" : 22135,
                "reduce" : 223,
                "output" : 2
        },
        "ok" : 1,
}

 

 看到results.value是Nan,證實此方法不可行。code

 

第二種方法:使用內置命令函數runCommand。

1)emit函數的第2參數直接使用數值。對象

> db.runCommand({mapReduce:"entities",map:function(){emit(this.age,1)},reduce:fu
nction(key,value){var total=0;for(var i in value){total+=value[i];} return {coun
t:total,key:key};},query:{age:{$gt:97}},out:{inline:1}})
{
        "results" : [
                {
                        "_id" : 98,
                        "value" : {
                                "count" : "0[object Object]11",
                                "key" : 98
                        }
                },
                {
                        "_id" : 99,
                        "value" : {
                                "count" : "0[object Object]111111111111111111111
11111111111111",
                                "key" : 99
                        }
                }
        ],
        "timeMillis" : 383,
        "counts" : {
                "input" : 22135,
                "emit" : 22135,
                "reduce" : 223,
                "output" : 2
        },
        "ok" : 1
}

 

看到results.value是居然是這樣的,證實此方法不可行。blog

2)emit函數的第2參數使用object對象。input

> db.runCommand({mapReduce:"entities",map:function(){emit(this.age,{count:1})},r
educe:function(key,value){var total=0;for(var i in value){total+=value[i].count;
} return {count:total,key:key};},query:{age:{$gt:98}},out:{inline:1}})
{
        "results" : [
                {
                        "_id" : 99,
                        "value" : {
                                "count" : 11533,
                                "key" : 99
                        }
                }
        ],
        "timeMillis" : 388,
        "counts" : {
                "input" : 11533,
                "emit" : 11533,
                "reduce" : 116,
                "output" : 1
        },
        "ok" : 1
}

 

看到results.value是正常值,方法可行。it

 

爲何會這樣?緣由之後再補上。

結論:

一、使用擴展函數db.xx.mapreduce時,emit函數的第2參數必須是使用數值。

2,使用內置命令函數db.runCommand時,emit函數的第2參數必須object對象。程序內部運行就是使用此方法。

相關文章
相關標籤/搜索