Puoi sicuramente farlo. Risponderò alle tue domande una alla volta:
1. È possibile specificare una query insieme a map-reduce, che filtra l'insieme di oggetti che verranno passati alla fase della mappa. Nella mongo shell, sembrerebbe (supponendo che m
e r
sono i nomi delle tue funzioni di mappatura e riduttore, rispettivamente):
> db.coll.mapReduce(m, r, {query: {$or: [{"recently-voted": true}, {"hourly-score": {$gt: 0}}]}})
2.Il passaggio n. 1 ti consentirà di utilizzare il tuo mapper su tutti i documenti con almeno un voto nell'ultima ora (o con recently-voted
impostato su true), ma non tutti i voti saranno stati registrati nell'ultima ora. Quindi dovrai filtrare l'elenco nel tuo mappatore ed emettere solo i voti che desideri contare:
function m() {
var hour_ago = new Date() - 3600000;
this.votes.forEach(function (vote) {
if (vote.ts > hour_ago) {
emit(/* your key */, this.vote.a);
}
});
}
E per ridurre:
function r(key, values) {
var sum = 0;
values.forEach(function(value) { sum += value; });
return sum;
}
3.Per aggiornare la tabella dei punteggi orari, puoi utilizzare il reduceOutput
opzione per ridurre la mappa, che chiamerà il riduttore sia con i valori emessi, sia con il valore precedentemente salvato nella raccolta di output, (se presente). Il risultato di tale passaggio verrà salvato nella raccolta di output. Questo è simile a:
> db.coll.mapReduce(m, r, {query: ..., out: {reduce: "output_coll"}})
Oltre a ridurre l'output, puoi utilizzare merge
che sovrascriverà i documenti nella raccolta di output con quelli appena creati (ma lasciando dietro di sé tutti i documenti con un _id
diverso da _id
s creati dal tuo lavoro m-r), replace
, che è effettivamente un'operazione di rilascio e creazione ed è l'impostazione predefinita, oppure utilizza {inline: 1}
, che restituirà i risultati direttamente alla shell o al tuo driver. Tieni presente che quando utilizzi {inline: 1}
, i risultati devono rientrare nelle dimensioni consentite per un singolo documento (16 MB nelle recenti versioni di MongoDB).
(4.) Puoi eseguire lavori di riduzione mappa su secondari ("slave"), ma poiché i secondari non possono accettare scritture (questo è ciò che li rende secondari), puoi farlo solo quando usi l'output inline.