1

我有以下查询从我的用户模式中返回一个随机用户:

UserSchema.statics.random = function(id,callback) {
  this.count(function(err, count) {
    if (err) {
      return callback(err);
    }
    var rand = Math.floor(Math.random() * count);
    this.findOne()
    .where('_id').ne(id)
    .where('last_active').gte(new Date(new Date().setDate(new Date().getDate()-3)))
    .skip(rand)
    .exec(callback);
  }.bind(this));
};

但是有时它会返回NULL-我认为这是因为它首先计算文档,然后应用过滤器来减少文档的数量,因此该rand值可能高于可用的文档数量。

我似乎想不出有什么更好的方法来做到这一点?

我会运行上面的查询,计算文档然后使用.skip()参数运行另一个查询吗?

4

1 回答 1

3

你不想要findOne(),你想要的只是find()但是limit(1).skip(rand)。正如@WiredPrairie 评论的那样,您还需要确保您的.count查询与您的查询相同,.find以便最大限度地减少跳过结尾的机会。count如果在 the和while 之间删除记录,它仍然是可能的find。这是一个未经测试的片段:

UserSchema.statics.random = function(id, callback) {
  var conditions = {
    _id: {$ne: id},
    //not sure WTF you are trying to do here, but consider moment.js
    // Users must be active within the last 3 days
    last_active: new Date(new Date().setDate(new Date().getDate()-3))
  };

  this.count(conditions, function(err, count) {
    if (err) {
      return callback(err);
    }
    var rand = Math.floor(Math.random() * count);
    this.find(conditions).limit(1).skip(rand).exec(callback);
  }.bind(this));
};
于 2013-10-02T17:50:23.657 回答