特别是对于聚合框架本身来说,实际上并没有任何本地方法,因为还没有可用的运算符来执行诸如生成随机数之类的操作。因此,无论您可能投射一个字段进行排序的任何匹配,都不会因为缺乏变化的种子值而“真正随机”。
更好的方法是在返回结果后将结果“洗牌”为数组。有多种“shuffle”实现,下面是 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;
}
但是,如果您实际上正在谈论对大量结果进行洗牌,例如在使用新方法获得的集合中$out http://docs.mongodb.org/manual/reference/operator/aggregation/out/运算符或实际上的任何集合,那么您可以使用mapReduce“作弊”。
db.collection.mapReduce(
function(){
var random = Math.floor( Math.random() * 100000 );
emit({ rand: random, id: this._id }, this );
},
function(){},
{ out: { replace: "newcollection" } }
);
这利用了 MapReduce 的特性,即键值始终是排序的。因此,通过包含随机数作为密钥的前导部分,您将始终获得随机排序的结果。