【问题标题】:MapReduce in mongo db is taking 0 input for large datamongo db 中的 MapReduce 对大数据采用 0 输入
【发布时间】:2016-09-05 12:31:40
【问题描述】:

我是 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 个文档的集合上返回错误结果。

下面是我的 map reduce 查询:

`
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 个输入...... 请注意我是在 amazon t2.micro ec2 实例上做的

【问题讨论】:

  • 您是否考虑过为同一任务创建更高效​​的聚合管道?看stackoverflow.com/questions/37938257/…
  • @chridam ...是的....我已经使用聚合完成了这个......但我想使用 mapreduce ......
  • @chridam :感谢您的建议..但是您能否解释一下我所做的是否有任何问题..因为我真的无法找出那里的缺陷.. ...我想使用 map reduce,因为我每天都会收到大量数据,并且想在上面使用增量 map reduce....
  • 不幸的是,我无法准确指出问题出在哪里,但会更多地欺骗使用聚合框架做完全相同的事情但性能比 MapReduce 更高的解决方案,因为 AF 管道已经过优化在其 C++ 代码中“在”MongoDB 中作为聚合框架运行,而另一方面,MapReduce 在捆绑的 JS 控制台中的 V8/spidermonkey(取决于您的版本)环境中在单独的线程中运行,并使用您提供的代码发出和减少文档的某些部分以在某些字段上进行聚合。
  • @chridam 感谢您的解释......但是任何想法为什么当我有一个较小的集合时它会起作用......我的意思是它在一个有 50k 文档的集合中完美运行但停止工作包含 5000k 文档的集合...PS:我现在也在 EC2 中等实例上尝试过

标签: mongodb mapreduce mongodb-query


【解决方案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();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2020-04-04
    • 1970-01-01
    • 1970-01-01
    • 2015-07-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多