mongo db中的MapReduce为大数据输入0输入

时间:2016-09-05 12:31:40

标签: mongodb mapreduce mongodb-query

我是mongo db的新手,并且map reduce,我遇到了这个问题。 以下是我的馆藏文件格式: -

`{ 
   "_id" : ObjectId("57c9b650d803090f7e43864c"), 
   "imei" : "2670988969039437", 
   "model" : "XYX", 
   "cId" : "168", 
   "src" : "XYZZZ", 
   "feedback" : "downloaded_gcm", 
   "ts" : "2016-08-04 09:51:18" 
 }`

当我在包含50000个文档的集合上测试它时,我的查询起作用,但它在包含50,00,000个文档的集合上返回了错误的结果。

下面是我的地图缩减查询:

`
db.colectionNAme.mapReduce(
function() {
    var key = this.model;
    var val = {
        installed : 0,
        received : 0,
        gcm_cancel : 0,
        downloaded_gcm : 0,
        gcm_acticated : 0,
        gcm_ok : 0
    };

     if(this.feedback == "installed") {
        val.installed++;
    } else if(this.feedback == "received") {
        val.received++;
    } else if(this.feedback == "gcm_cancel") {
        val.gcm_cancel++;
    } else if(this.feedback == "downloaded_gcm") {
        val.downloaded_gcm++;
    } else if(this.feedback == "gcm_acticated") {
        val.gcm_acticated++;
    } else if(this.feedback == "gcm_ok") {
        val.gcm_ok++;
    }
    emit(key, val);
},

function(key,values) {
    var val = {
        installed : 0,
        received : 0,
        gcm_cancel : 0,
        downloaded_gcm : 0,
        gcm_acticated : 0,
        gcm_ok : 0
    };

    values.forEach(function( value ) {
        val.installed += value.installed;
        val.received += value.received;
        val.gcm_cancel += value.gcm_cancel;
        val.downloaded_gcm += value.downloaded_gcm;
        val.gcm_acticated += value.gcm_acticated;
        val.gcm_ok += value.gcm_ok;
    });

    return val;
},
{   
    query:{cId : "166"},
    out:"mapRedResults",
    sort:{model:1},
    jsMode: true,
    usev8 :true
}
);`

这是它给出的输出: -

{
  "result" : "mapRedResults",
  "timeMillis" : 2221,
  "counts" : {
    "input" : 0,
    "emit" : 0,
    "reduce" : 0,
    "output" : 0
  },
  "ok" : 1
}

从结果中可以看出..它需要输入0 ... 请注意我是在亚马逊t2.micro ec2实例

上进行的

1 个答案:

答案 0 :(得分:1)

不幸的是,我无法确切地指出问题的确切位置,但会更加倾向于使用聚合框架执行完全相同但具有比MapReduce更高性能的解决方案,因为AF管道在“MongoDB内部”运行时进行了优化在其C ++代码中作为聚合框架,而MapReduce在另一方面在捆绑的JS控制台中的V8 / spidermonkey(取决于您的版本)环境中运行在单独的线程中,并使用您提供的代码来发出和减少部分文档在某些领域聚合。

对于使用聚合框架的解决方案,您可以查看Get count of “loglevel” for each “name”指针。

如果由于某种原因你坚持使用mapReduce,我建议你重构代码,以避免不必要的变量检查和分配,方法是动态地创建一个反馈值作为属性的对象。

例如,您可以简单地运行相同的mapReduce操作:

map = function() {
    if (!this.feedback) return;
    var obj = {};
    obj[this.feedback] = 1;    
    emit(this.model, obj);
};

reduce = function(key, values) {
   var counts = {};
   values.forEach(function(v) {
        for(var k in v) { 
            if(!counts[k]) 
                counts[k] = 0
            counts[k] += v[k];
        }
    });

    return counts;
};

myMapReduce = db.runCommand({
    "mapreduce": "colectionNAme",
    "map": map,
    "reduce" : reduce, 
    "out": "mappedResults"
});

db[myMapReduce.result].find();