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

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

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


当前回答

从MongoDB 3.2版本开始,你可以使用$sample聚合管道操作符从集合中随机获得N个文档:

// Get one random document from the mycoll collection.
db.mycoll.aggregate([{ $sample: { size: 1 } }])

如果你想从集合的筛选子集中选择随机文档,在管道中预先添加$match阶段:

// Get one random document matching {a: 10} from the mycoll collection.
db.mycoll.aggregate([
    { $match: { a: 10 } },
    { $sample: { size: 1 } }
])

正如注释中所指出的,当size大于1时,返回的文档样例中可能有重复项。

其他回答

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

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

现在可以使用聚合了。 例子:

db.users.aggregate(
   [ { $sample: { size: 3 } } ]
)

去看医生。

如果你有一个简单的id键,你可以将所有的id存储在一个数组中,然后随机选择一个id。(Ruby回答):

ids = @coll.find({},fields:{_id:1}).to_a
@coll.find(ids.sample).first

从MongoDB 3.2版本开始,你可以使用$sample聚合管道操作符从集合中随机获得N个文档:

// Get one random document from the mycoll collection.
db.mycoll.aggregate([{ $sample: { size: 1 } }])

如果你想从集合的筛选子集中选择随机文档,在管道中预先添加$match阶段:

// Get one random document matching {a: 10} from the mycoll collection.
db.mycoll.aggregate([
    { $match: { a: 10 } },
    { $sample: { size: 1 } }
])

正如注释中所指出的,当size大于1时,返回的文档样例中可能有重复项。

为了获得确定数量的无重复的随机文档:

first get all ids get size of documents loop geting random index and skip duplicated number_of_docs=7 db.collection('preguntas').find({},{_id:1}).toArray(function(err, arr) { count=arr.length idsram=[] rans=[] while(number_of_docs!=0){ var R = Math.floor(Math.random() * count); if (rans.indexOf(R) > -1) { continue } else { ans.push(R) idsram.push(arr[R]._id) number_of_docs-- } } db.collection('preguntas').find({}).toArray(function(err1, doc1) { if (err1) { console.log(err1); return; } res.send(doc1) }); });