Ich würde vorschlagen, map / redu zu verwenden, wobei Sie die Map-Funktion verwenden, um nur zu emittieren, wenn ein zufälliger Wert über einer bestimmten Wahrscheinlichkeit liegt.
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);
Die obige Reduktionsfunktion funktioniert, da nur eine Taste ('1') von der Kartenfunktion ausgegeben wird.
Der Wert der "Wahrscheinlichkeit" wird beim Aufrufen von mapRreduce (...) im "Bereich" definiert.
Die Verwendung von mapReduce wie diesem sollte auch für eine Sharded-Datenbank verwendbar sein.
Wenn Sie genau n von m Dokumenten aus der Datenbank auswählen möchten, können Sie dies folgendermaßen tun:
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);
Dabei ist "countTotal" (m) die Anzahl der Dokumente in der Datenbank und "countSubset" (n) die Anzahl der abzurufenden Dokumente.
Dieser Ansatz kann bei Sharded-Datenbanken zu Problemen führen.