我想从一个巨大的集合(1亿条记录)中获得一个随机记录。

最快最有效的方法是什么?

数据已经在那里,没有字段可以生成随机数并获得随机行。


当前回答

MongoDB现在有$rand

要选择n个非重复项,请使用{$addFields: {_f: {$rand:{}}}}进行聚合,然后按_f进行$sort和$limit n。

其他回答

您还可以使用MongoDB的地理空间索引功能来选择与随机数“最近”的文档。

首先,在集合上启用地理空间索引:

db.docs.ensureIndex( { random_point: '2d' } )

用x轴上的随机点创建一堆文档:

for ( i = 0; i < 10; ++i ) {
    db.docs.insert( { key: i, random_point: [Math.random(), 0] } );
}

然后你可以像这样从集合中随机获得一个文档:

db.docs.findOne( { random_point : { $near : [Math.random(), 0] } } )

或者你可以检索几个文档最近的随机点:

db.docs.find( { random_point : { $near : [Math.random(), 0] } } ).limit( 4 )

这只需要一个查询,没有空检查,加上代码干净,简单和灵活。您甚至可以使用地理点的y轴为查询添加第二个随机性维度。

我最简单的解决办法是……

db.coll.find()
    .limit(1)
    .skip(Math.floor(Math.random() * 500))
    .next()

你至少有500件收藏品

您可以选择随机_id并返回相应的对象:

 db.collection.count( function(err, count){
        db.collection.distinct( "_id" , function( err, result) {
            if (err)
                res.send(err)
            var randomId = result[Math.floor(Math.random() * (count-1))]
            db.collection.findOne( { _id: randomId } , function( err, result) {
                if (err)
                    res.send(err)
                console.log(result)
            })
        })
    })

在这里,你不需要花空间存储随机数字的集合。

您还可以在执行查询后使用shuffle-array

Var shuffle = require('shuffle-array');

Accounts.find (qry函数(呃,results_array) { newIndexArr = shuffle (results_array);

对所有记录进行计数,生成一个0到计数之间的随机数,然后执行:

db.yourCollection.find().limit(-1).skip(yourRandomNumber).next()