我有以下查询从我的用户架构中返回一个随机用户:
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()
参数运行另一个查询?
答案 0 :(得分:3)
您不希望findOne()
,只需要find()
,只需要limit(1).skip(rand)
。正如@WiredPrairie所评论的那样,您还需要确保.count
查询与.find
查询相同,以便最大限度地减少跳过结束的可能性。如果在count
和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));
};