In particolare per il framework di aggregazione stesso non esiste un modo nativo in quanto non è ancora disponibile un operatore per fare qualcosa come generare un numero casuale. Quindi, qualunque corrispondenza tu possa proiettare su un campo su cui eseguire l'ordinamento non sarebbe "veramente casuale" per mancanza di un valore di seed mutevole.
L'approccio migliore consiste nel "mescolare" i risultati come una matrice dopo che il risultato è stato restituito. Esistono varie implementazioni "shuffle", eccone una per JavaScript:
function shuffle(array) {
var currentIndex = array.length
, temporaryValue
, randomIndex
;
while (0 !== currentIndex) {
randomIndex = Math.floor(Math.random() * currentIndex);
currentIndex -= 1;
temporaryValue = array[currentIndex];
array[currentIndex] = array[randomIndex];
array[randomIndex] = temporaryValue;
}
return array;
}
Ma se stai effettivamente parlando di mescolare un gran numero di risultati come in una raccolta ottenuta dall'uso del nuovo $out
operator o qualsiasi collezione, infatti, puoi "barare" usando mapReduce.
db.collection.mapReduce(
function(){
var random = Math.floor( Math.random() * 100000 );
emit({ rand: random, id: this._id }, this );
},
function(){},
{ out: { replace: "newcollection" } }
);
Ciò sfrutta la natura di mapReduce in quanto il valore della chiave è sempre ordinato. Quindi, includendo un numero casuale come parte iniziale della chiave, otterrai sempre un risultato ordinato casuale.