来自Mongoose集合的随机文档

use*_*104 18 javascript mongoose node.js

我想创建一个Schema.statics.random函数,从集合中获取一个随机元素.我知道有一个本机MongoDB驱动程序的例子,但我无法让它在Mongoose中运行.

小智 30

我在GitHub Gist中找到了这个Mongoose Schema静态函数,它应该实现你所追求的目标.它计算集合中的文档数量,然后在跳过随机数量后返回一个文档.

QuoteSchema.statics.random = function(callback) {
  this.count(function(err, count) {
    if (err) {
      return callback(err);
    }
    var rand = Math.floor(Math.random() * count);
    this.findOne().skip(rand).exec(callback);
  }.bind(this));
};
Run Code Online (Sandbox Code Playgroud)

资料来源:https://gist.github.com/3453567

NB我稍微修改了一下代码以使其更具可读性.


Eat*_*oes 13

如果您不想在模式中添加"类似测试"代码,则使用Mongoose查询.

Model.count().exec(function(err, count){

  var random = Math.floor(Math.random() * count);

  Model.findOne().skip(random).exec(
    function (err, result) {

      // result is random 

  });

});
Run Code Online (Sandbox Code Playgroud)

  • @PrathameshMore 1)`Model.count()`检索集合中实际有多少文档。2) `Math....` 得到一个在统计文档范围内的随机整数。3) 最后,我们使用“skip”函数使用“findOne()”再次点击 mongo,以获取索引到范围内随机数的单个文档。 (3认同)

Ioa*_*nna 8

一个更短但可能更高效的解决方案
(我们不会遍历集合一次来计数和第二次跳过元素,但猫鼬可能会在幕后这样做):

使用聚合和 $sample

Model.aggregate([{ $sample: { size: 1 } }])
Run Code Online (Sandbox Code Playgroud)


mar*_*nho 7

您可以使用聚合:

User.aggregate([
    {$match: {gender: "male"}},
    {$sample: {size: 10}}
], function(err, docs) {
    console.log(docs);
});
Run Code Online (Sandbox Code Playgroud)

或者你可以使用 npm 包https://www.npmjs.com/package/mongoose-simple-random

User.findRandom({gender: "male"}, {}, {limit: 10}, function(err, results) { 
    console.log(results); // 10 elements
});
Run Code Online (Sandbox Code Playgroud)

  • 这应该被标记为答案 (3认同)

Mih*_*scu 6

我已经为mongoose实现了一个插件,它使用2dsphere索引在两个随机生成的坐标上使用$ near查询以非常有效的方式执行此操作.请在此处查看:https://github.com/matomesc/mongoose-random.