2013-01-03 77 views
3
不工作

我寫的,其中記錄按以下格式發出的MapReduce的功能MongoDB中的MapReduce:如預期超過1000條記錄

{userid:<xyz>, {event:adduser, count:1}} 
{userid:<xyz>, {event:login, count:1}} 
{userid:<xyz>, {event:login, count:1}} 
{userid:<abc>, {event:adduser, count:1}} 

其中userid是關鍵,其餘都是該鍵的值。 MapReduce的功能後,我想要得到的結果如下格式

{userid:<xyz>,{events: [{adduser:1},{login:2}], allEventCount:3}} 

要達致這我寫了下面同時減少在聚合框架和MapReduce功能 我知道這可以通過組通過以下方式實現..,但是我們需要類似的功能來處理複雜的情況。所以,我正在採取這種方法。

var reducefn = function(key,values){ 
var result = {allEventCount:0, events:[]}; 
values.forEach(function(value){ 
    var notfound=true; 
    for(var n = 0; n < result.events.length; n++){ 
     eventObj = result.events[n]; 
     for(ev in eventObj){ 
      if(ev==value.event){ 
       result.events[n][ev] += value.allEventCount; 
       notfound=false; 
       break; 
      } 
     } 
    } 
    if(notfound==true){ 
     var newEvent={} 
     newEvent[value.event]=1; 
     result.events.push(newEvent); 
    } 
    result.allEventCount += value.allEventCount; 
}); 
return result; 

}

這完美運行,當我運行了1000條記錄,當有3K或10K的記錄,結果我得到的是這樣的

{ "_id" : {...}, "value" :{"allEventCount" :30, "events" :[ { "undefined" : 1}, 
{"adduser" : 1 }, {"remove" : 3 }, {"training" : 1 }, {"adminlogin" : 1 }, 
{"downgrade" : 2 } ]} } 

無法理解undefined來自哪裏,而且各個事件的和小於allEventCount。集合中的所有文檔都有非空字段event,所以不會有未定義的機會。

Mongo DB版本 - 2.2.1 環境 - 本地機器,不分片。

在縮小功能中,當類似操作result.allEventCount += value.allEventCount;通過時,爲什麼此操作失敗result.events[n][ev] += value.allEventCount;

修正答案由johnyHK

的建議

Reduce函數:

var reducefn = function(key,values){ 
    var result = {totEvents:0, event:[]}; 
    values.forEach(function(value){ 
     value.event.forEach(function(eventElem){ 
      var notfound=true; 
      for(var n = 0; n < result.event.length; n++){ 
       eventObj = result.event[n]; 
       for(ev in eventObj){ 
       for(evv in eventElem){ 
        if(ev==evv){ 
         result.event[n][ev] += eventElem[evv]; 
         notfound=false; 
         break; 
        } 
       }} 
      } 
      if(notfound==true){ 
       result.event.push(eventElem); 
      } 
     }); 
     result.totEvents += value.totEvents; 
    }); 
    return result; 
} 

回答

2

的對象,你emit從您map功能的形狀必須是一樣的物體從reduce函數返回,如在處理大量文檔(如本例中)時,reduce的結果可能會反饋回reduce

所以,你需要改變你的emit發出的文檔是這樣的:

{userid:<xyz>, {events:[{adduser: 1}], allEventCount:1}} 
{userid:<xyz>, {events:[{login: 1}], allEventCount:1}} 

,然後相應地更新您的reduce功能。

+0

謝謝@JohnyHK。這是問題,現在已經解決了。 – Sundar

相關問題