我想从一个巨大的集合(1亿条记录)中获得一个随机记录。
最快最有效的方法是什么?
数据已经在那里,没有字段可以生成随机数并获得随机行。
我想从一个巨大的集合(1亿条记录)中获得一个随机记录。
最快最有效的方法是什么?
数据已经在那里,没有字段可以生成随机数并获得随机行。
当前回答
没有一个解决方案对我有效。尤其是当缝隙多、集小的时候。 这对我来说很好(在php中):
$count = $collection->count($search);
$skip = mt_rand(0, $count - 1);
$result = $collection->find($search)->skip($skip)->limit(1)->getNext();
其他回答
使用Python (pymongo),聚合函数也可以工作。
collection.aggregate([{'$sample': {'size': sample_size }}])
这种方法比对随机数(例如collection.find([random_int]))运行查询要快得多。对于大型收藏来说尤其如此。
我的PHP/MongoDB排序/顺序随机解决方案。希望这对大家有所帮助。
注意:我在我的MongoDB集合中有数字ID,引用一个MySQL数据库记录。
首先,我用10个随机生成的数字创建一个数组
$randomNumbers = [];
for($i = 0; $i < 10; $i++){
$randomNumbers[] = rand(0,1000);
}
在我的聚合中,我使用$addField管道操作符结合$arrayElemAt和$mod(模)。模数运算符将给我一个从0到9的数字,然后我用它从随机生成的数字数组中选择一个数字。
$aggregate[] = [
'$addFields' => [
'random_sort' => [ '$arrayElemAt' => [ $randomNumbers, [ '$mod' => [ '$my_numeric_mysql_id', 10 ] ] ] ],
],
];
在此之后,您可以使用Pipeline排序。
$aggregate[] = [
'$sort' => [
'random_sort' => 1
]
];
我最简单的解决办法是……
db.coll.find()
.limit(1)
.skip(Math.floor(Math.random() * 500))
.next()
你至少有500件收藏品
我建议给每个对象添加一个随机的int字段。然后你就可以做
findOne({random_field: {$gte: rand()}})
随机选择一个文档。只要确保你ensureIndex({random_field:1})
如果您使用的是mongoid(文档到对象的包装器),您可以执行以下操作 Ruby。(假设你的模型是User)
User.all.to_a[rand(User.count)]
在我的。irbrc,我有
def rando klass
klass.all.to_a[rand(klass.count)]
end
所以在rails控制台,我可以做,例如,
rando User
rando Article
从任何集合中随机获取文件。