Suggerirei di usare map / ridurre, dove usi la funzione map per emettere solo quando un valore casuale è al di sopra di una data probabilità.
function mapf() {
if(Math.random() <= probability) {
emit(1, this);
}
}
function reducef(key,values) {
return {"documents": values};
}
res = db.questions.mapReduce(mapf, reducef, {"out": {"inline": 1}, "scope": { "probability": 0.5}});
printjson(res.results);
La funzione di riduzione di cui sopra funziona perché un solo tasto ('1') viene emesso dalla funzione mappa.
Il valore della "probabilità" è definito nell '"ambito", quando si richiama mapRreduce (...)
L'uso di mapReduce in questo modo dovrebbe essere utilizzabile anche su un db ridotto.
Se si desidera selezionare esattamente n di m documenti dal db, è possibile farlo in questo modo:
function mapf() {
if(countSubset == 0) return;
var prob = countSubset / countTotal;
if(Math.random() <= prob) {
emit(1, {"documents": [this]});
countSubset--;
}
countTotal--;
}
function reducef(key,values) {
var newArray = new Array();
for(var i=0; i < values.length; i++) {
newArray = newArray.concat(values[i].documents);
}
return {"documents": newArray};
}
res = db.questions.mapReduce(mapf, reducef, {"out": {"inline": 1}, "scope": {"countTotal": 4, "countSubset": 2}})
printjson(res.results);
Dove "countTotal" (m) è il numero di documenti nel db e "countSubset" (n) è il numero di documenti da recuperare.
Questo approccio potrebbe dare alcuni problemi su database frammentati.