Определено можете да направите това. Ще отговоря на въпросите ви един по един:
1. Можете да зададете заявка заедно с вашата map-reduce, която филтрира набора от обекти, които ще бъдат предадени във фазата на картата. В mongo shell това би изглеждало така (приемайки m
и r
са съответно имената на вашите функции за картографиране и редуктор):
> db.coll.mapReduce(m, r, {query: {$or: [{"recently-voted": true}, {"hourly-score": {$gt: 0}}]}})
2. Стъпка #1 ще ви позволи да използвате своя картограф на всички документи с поне едно гласуване през последния час (или с recently-voted
зададено на true), но не всички гласове ще са били през последния час. Така че ще трябва да филтрирате списъка във вашия картограф и да излъчвате само онези гласове, които искате да преброите:
function m() {
var hour_ago = new Date() - 3600000;
this.votes.forEach(function (vote) {
if (vote.ts > hour_ago) {
emit(/* your key */, this.vote.a);
}
});
}
И за намаляване:
function r(key, values) {
var sum = 0;
values.forEach(function(value) { sum += value; });
return sum;
}
3. За да актуализирате таблицата с почасови резултати, можете да използвате reduceOutput
опция за map-reduce, която ще извика вашия редуктор както с излъчените стойности, така и с предварително запазената стойност в изходната колекция (ако има такава). Резултатът от това преминаване ще бъде записан в изходната колекция. Това изглежда така:
> db.coll.mapReduce(m, r, {query: ..., out: {reduce: "output_coll"}})
В допълнение към повторното намаляване на изхода, можете да използвате merge
което ще презапише документите в изходната колекция с новосъздадени (но оставя зад себе си всички документи с _id
различен от _id
е създадено от вашето m-r задание), replace
, което на практика е операция за пускане и създаване и е по подразбиране, или използвайте {inline: 1}
, който ще върне резултатите директно в обвивката или на вашия драйвер. Имайте предвид, че когато използвате {inline: 1}
, вашите резултати трябва да се поберат в размера, разрешен за един документ (16 MB в последните версии на MongoDB).
(4.) Можете да изпълнявате задания за намаляване на картата на вторични („подчинени“), но тъй като вторичните не могат да приемат записи (това ги прави вторични), можете да направите това само когато използвате вграден изход.