是否可以从MongoDB检索多个随机的、非顺序的文档?

是否可以从MongoDB检索多个随机的、非顺序的文档?,mongodb,random,mongoose,Mongodb,Random,Mongoose,我想从MongoDB数据库中检索一组随机文档。到目前为止,在谷歌搜索了很多次之后,我只看到了检索一个随机文档或一组文档的方法,这些文档从一个随机跳过的位置开始,但文档仍然是连续的 我尝试过mongoose simple random,但不幸的是它没有检索到“真实”的随机集。它所做的是跳到一个随机位置,然后从该位置检索n个文档 相反,我希望像MySQL一样使用一个查询(或最少数量的查询)检索一个随机集,我需要这个列表每次都是随机的。我需要这是高效的——与MySQL这样的查询相对应。我想在Mongo

我想从MongoDB数据库中检索一组随机文档。到目前为止,在谷歌搜索了很多次之后,我只看到了检索一个随机文档或一组文档的方法,这些文档从一个随机跳过的位置开始,但文档仍然是连续的

我尝试过mongoose simple random,但不幸的是它没有检索到“真实”的随机集。它所做的是跳到一个随机位置,然后从该位置检索n个文档

相反,我希望像MySQL一样使用一个查询(或最少数量的查询)检索一个随机集,我需要这个列表每次都是随机的。我需要这是高效的——与MySQL这样的查询相对应。我想在MongoDB中复制以下内容:

SELECT * FROM products ORDER BY rand() LIMIT 50;
这可能吗?我使用的是Mongoose,但是使用任何适配器的示例——甚至是直接的MongoDB查询——都很酷


我见过一种向每个文档中添加一个字段、为每个字段生成一个随机值并使用
{rand:{$gte:rand()}
我们希望随机的每个查询的方法。但是,我担心的是,理论上两个查询可能返回同一个集合。

您可以执行两个请求,但要以高效的方式:

  • 您的第一个请求只是获取您的集合中所有文档的“\u id”列表。确保使用mongo投影
    db.products.find({},{''u id':1})
  • 您有一个“_id”列表,只需从列表中随机选择N
  • 使用$in运算符执行第二个查询
  • 特别重要的是,第一个查询完全由索引支持(因为它是“\u id”)。此索引可能已完全存储在内存中(否则可能会出现性能问题)。因此,在运行第一个查询时只读取索引,而且速度非常快

    虽然第二个查询意味着读取实际的文档,但索引将有很大帮助


    如果你可以这样做,你应该试试。

    我不认为MySQL
    ORDER BY rand()
    特别有效——据我所知,它本质上是给每一行分配一个随机数,然后在这个随机数列上对表进行排序,并返回前N个结果


    如果您愿意接受对集合的插入的一些开销,那么可以将问题简化为在一个范围内生成N个随机整数。为每个文档添加计数器字段:每个文档将按顺序分配一个唯一的正整数。无论什么文档得到什么数字,只要赋值是唯一的,数字是连续的,并且您不删除文档,或者使计数器文档方案复杂化以处理漏洞。您可以通过两步完成插入。在一个单独的
    计数器
    集合中,保存一份包含第一个未用于计数器的编号的文档。插入时,首先
    查找并修改计数器文档,以检索下一个计数器值,并以原子方式递增计数器值。然后插入带有计数器值的新文档。要查找N个随机值,请查找最大计数器值,然后在最大计数器定义的范围内生成N个不同的随机数,然后使用
    $in
    检索文档。大多数语言都应该有一个随机的库来处理一个范围内的n个随机整数。

    如果你可以“检索一个随机文档”,那么你可以通过重复来检索多个,不是吗?我认为这是低效的——我需要它与MySQL RAND()排序查询相符合。如果我的集合中有500000个文档,这仍然是有效的吗?@ChadJohnson-nah,甚至不是很接近,你需要一个单独的字段:尝试查看除第一个答案以外的任何内容there@Chad约翰逊:了解它的最好方法可能是试穿你的收藏品。对于第一个请求,为了实现您的目标(真正的随机文档),您不应该使用限制。但是,如果您只是想测试第一个请求是否意味着生产系统中的某些内容过于密集,那么您可以尝试使用1000,然后5000,25000。。。直到你达到收集的文档数量并确认所有内容都正确为止。@Sammaye:你能链接到具体的答案吗?根据你的说法,这项工作是挑选N个(例如50个)随机文档的最佳方式吗?对于这种特定的场景,直接索引查询只提取需要的内容“只要赋值是唯一的,数字是连续的”->只要文档从未被删除,我也会添加。rand()不是吗如果我没记错的话,实际上是从桌上的AI键中选择的?@dotpush-非常好。它确实要求不删除文档。我已经编辑了答案。您可以使编号方案更加复杂,以允许删除。我认为,对于许多用例来说,仅仅进行一次随机绘图可能比围绕绘图样本构建集合的使用更容易。