Du kan definitivt göra detta. Jag tar upp dina frågor en i taget:
1. Du kan ange en fråga tillsammans med din map-reduce, som filtrerar uppsättningen objekt som kommer att skickas in i kartfasen. I mongoskalet skulle detta se ut (förutsatt att m
och r
är namnen på dina mappar- och reducerfunktioner, respektive):
> db.coll.mapReduce(m, r, {query: {$or: [{"recently-voted": true}, {"hourly-score": {$gt: 0}}]}})
2. Steg #1 låter dig använda din kartläggare på alla dokument med minst en röst under den senaste timmen (eller med recently-voted
satt till sant), men alla röster kommer inte att ha skett under den senaste timmen. Så du måste filtrera listan i din kartläggare och bara avge de röster du vill räkna:
function m() {
var hour_ago = new Date() - 3600000;
this.votes.forEach(function (vote) {
if (vote.ts > hour_ago) {
emit(/* your key */, this.vote.a);
}
});
}
Och för att minska:
function r(key, values) {
var sum = 0;
values.forEach(function(value) { sum += value; });
return sum;
}
3. För att uppdatera tabellen över timpoäng kan du använda reduceOutput
alternativet för att map-reducera, vilket kommer att anropa din reducerare med både de utsända värdena och det tidigare sparade värdet i utdatasamlingen (om någon). Resultatet av det passet kommer att sparas i utdatasamlingen. Det här ser ut så här:
> db.coll.mapReduce(m, r, {query: ..., out: {reduce: "output_coll"}})
Förutom att minska utdata kan du använda merge
som kommer att skriva över dokument i utdatasamlingen med nyskapade (men lämnar efter sig alla dokument med en _id
annorlunda än _id
skapas av ditt m-r-jobb), replace
, som faktiskt är en släpp-och-skapa-operation och är standard, eller använd {inline: 1}
, som returnerar resultaten direkt till skalet eller till din drivrutin. Observera att när du använder {inline: 1}
, dina resultat måste passa i den tillåtna storleken för ett enskilt dokument (16 MB i de senaste MongoDB-versionerna).
(4.)Du kan köra map-reduce-jobb på sekundärer ("slavar"), men eftersom sekundärer inte kan acceptera skrivningar (det är det som gör dem sekundära), kan du bara göra detta när du använder inline-utdata.