Eu sugeriria usar o mapa / reduzir, onde você usa a função de mapa para emitir apenas quando um valor aleatório está acima de uma determinada probabilidade.
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);
A função reduzem-se acima funciona porque apenas uma tecla ('1') é emitida a partir da função de mapa.
O valor da "probabilidade" é definido no "escopo", ao chamar mapRreduce (...)
Usar o mapReduce como esse também deve ser usado em um banco de dados fragmentado.
Se você quiser selecionar exatamente n de m documentos no banco de dados, faça o seguinte:
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);
Onde "countTotal" (m) é o número de documentos no banco de dados e "countSubset" (n) é o número de documentos a serem recuperados.
Essa abordagem pode causar alguns problemas em bancos de dados fragmentados.