Du kan helt sikkert gøre dette. Jeg besvarer dine spørgsmål ét ad gangen:
1. Du kan angive en forespørgsel sammen med dit kort-reducer, som filtrerer det sæt af objekter, som vil blive sendt ind i kortfasen. I mongo-skallen ville dette se ud (forudsat m
og r
er navnene på dine mapper- og reducerfunktioner, henholdsvis):
> db.coll.mapReduce(m, r, {query: {$or: [{"recently-voted": true}, {"hourly-score": {$gt: 0}}]}})
2. Trin #1 giver dig mulighed for at bruge din mapper på alle dokumenter med mindst én stemme inden for den sidste time (eller med recently-voted
sat til sand), men ikke alle stemmer vil have været inden for den sidste time. Så du skal filtrere listen i din mapper og kun udsende de stemmer, du ønsker at tælle:
function m() {
var hour_ago = new Date() - 3600000;
this.votes.forEach(function (vote) {
if (vote.ts > hour_ago) {
emit(/* your key */, this.vote.a);
}
});
}
Og for at reducere:
function r(key, values) {
var sum = 0;
values.forEach(function(value) { sum += value; });
return sum;
}
3. For at opdatere timeresultattabellen kan du bruge reduceOutput
mulighed for at kort-reducere, hvilket vil kalde din reducer med både de udsendte værdier og den tidligere gemte værdi i outputsamlingen (hvis nogen). Resultatet af det pass vil blive gemt i outputsamlingen. Dette ser sådan ud:
> db.coll.mapReduce(m, r, {query: ..., out: {reduce: "output_coll"}})
Ud over at re-reducere output, kan du bruge merge
som vil overskrive dokumenter i outputsamlingen med nyoprettede (men efterlade alle dokumenter med en _id
anderledes end _id
s oprettet af dit m-r job), replace
, som faktisk er en drop-and-create-handling og er standard, eller brug {inline: 1}
, som returnerer resultaterne direkte til shellen eller til din driver. Bemærk, at når du bruger {inline: 1}
, skal dine resultater passe til den tilladte størrelse for et enkelt dokument (16 MB i de seneste MongoDB-udgivelser).
(4.)Du kan køre kort-reducerende job på sekundære ("slaves"), men da sekundære programmer ikke kan acceptere skrivninger (det er det, der gør dem sekundære), kan du kun gøre dette, når du bruger inline output.