Мой подход ниже:
, глядя на hadoop Я нашел подход CompositeInputFormat кратко, он принимает две или более коллекций в качестве входных данных для задания сокращения карты
согласно моему исследованиюmongodb пока не предоставляет этого.mongodb mapReduce выполняется для одной коллекции за раз. (пожалуйста, исправьте, если я беспокоюсь)
, поэтому я решил поместить коллекции, которые необходимо объединить, в одну коллекцию, для которой я буду выполнять mapreduce для "sql right join "
это из моего проекта репортера журналов.первого фазового сокращения карты достаточно, чтобы выполнить правильное объединение в случае "отсутствия часов".вторая фазовая карта-уменьшение имеет целью исключить лишнее правое соединение, вызванное полем часов.
db.test.drop();
db.test.insert({"username" : 1, "day" : 1, "clock" : 0 });
db.test.insert({"username" : 1, "day" : 1, "clock" : 1 });
db.test.insert({"username" : 1, startDay : 1,endDay:2, "table" : "user" });
//startDay : 1,endDay:2 are used to define the employers working day (join to company - left the company)
//you can use an array instedad of array here. for example day:[1,2,3, ...]
m1 = function(){
if( typeof this.table!= "undefined" && this.table!=null){
username = this.username;
startDay = this.startDay;
endDay = this.endDay;
while(startDay<=endDay){
emit({username:username,day:startDay},{clocks:["join"]});
// emit({username:username,day:startDay},1);
startDay++;
}
}else{
emit({username:this.username,day:this.day},{clocks:[this.clock]});
}
}
r1 = function(key,values){
result = {clocks:[]}
values.forEach(function(x){
result.clocks = x.clocks.concat(result.clocks);
result.clocks=result.clocks.filter(function(element, index, array){
return element!="join";
})
})
return result;
}
db.test.mapReduce(m1,r1,{out:"result1"})
db.test.find();
db.result1.find();
m2=function(){
key=this._id;
this.value.clocks.forEach(function(x){
key.clock=x;
emit(key,1);
})
}
r2 = function(key,values){
value=0;
values.forEach(function(x){
value+=1;
})
return result;
}
db.result1.mapReduce(m2,r2,{out:"result2"})
db.test.find();
db.result2.find();