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

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

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


当前回答

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

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

其他回答

在Mongoose中最好的方法是使用$sample进行聚合调用。 然而,Mongoose并不会将Mongoose文档应用到Aggregation上——尤其是当populate()也被应用的时候。

从数据库中获取一个“精益”数组:

/*
Sample model should be init first
const Sample = mongoose …
*/

const samples = await Sample.aggregate([
  { $match: {} },
  { $sample: { size: 33 } },
]).exec();
console.log(samples); //a lean Array

获取mongoose文档数组:

const samples = (
  await Sample.aggregate([
    { $match: {} },
    { $sample: { size: 27 } },
    { $project: { _id: 1 } },
  ]).exec()
).map(v => v._id);

const mongooseSamples = await Sample.find({ _id: { $in: samples } });

console.log(mongooseSamples); //an Array of mongoose documents

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

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

对于我来说,我想以随机顺序获得相同的记录,所以我创建了一个用于排序的空数组,然后生成1到7之间的随机数(我有7个字段)。每次我得到一个不同的值,我分配一个不同的随机排序。 这是“外行”,但对我来说很管用。

//generate random number
const randomval = some random value;
//declare sort array and initialize to empty

const sort = [];

//write a conditional if else to get to decide which sort to use

if(randomval == 1)
{


sort.push(...['createdAt',1]);

}

else if(randomval == 2)

{
   sort.push(...['_id',1]);
}

....
else if(randomval == n)
{
   sort.push(...['n',1]);
}

MongoDB现在有$rand

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

您可以选择随机_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)
            })
        })
    })

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