W szczególności dla samej struktury agregacji tak naprawdę nie ma żadnego natywnego sposobu, ponieważ nie ma jeszcze dostępnego operatora, aby zrobić coś takiego, jak wygenerowanie liczby losowej. Tak więc dowolne dopasowanie, na którym można by zaprojektować pole do sortowania, nie byłoby „naprawdę losowe” z powodu braku zmieniającej się wartości początkowej.
Lepszym podejściem jest "tasowanie" wyników jako tablicy po zwróceniu wyniku. Istnieją różne implementacje "shuffle", oto jedna dla 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;
}
Ale jeśli rzeczywiście mówisz o tasowaniu dużej liczby wyników, na przykład w kolekcji uzyskanej z użycia nowego $out
operatora lub jakiejkolwiek kolekcji, możesz "oszukiwać" za pomocą mapReduce.
db.collection.mapReduce(
function(){
var random = Math.floor( Math.random() * 100000 );
emit({ rand: random, id: this._id }, this );
},
function(){},
{ out: { replace: "newcollection" } }
);
Wykorzystuje to naturę mapReduce, ponieważ wartość klucza jest zawsze sortowana. Włączając liczbę losową jako wiodącą część klucza, zawsze otrzymasz losowo uporządkowany wynik.