Случайный документ из коллекции в Mongoose - программирование

Случайный документ из коллекции в Mongoose

Я хочу создать функцию Schema.statics.random, которая доставит мне случайный элемент из коллекции. Я знаю, что есть пример для родного драйвера MongoDB, но я не могу заставить его работать в Mongoose.

4b9b3361

Ответ 1

Я нашел эту статическую функцию Mongoose Schema в GitHub Gist, которая должна достичь того, что вам нужно. Он подсчитывает количество документов в коллекции и затем возвращает один документ после пропуска случайной суммы.

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));
};

Источник: https://gist.github.com/3453567

NB Я немного изменил код, чтобы сделать его более читаемым.

Ответ 2

Если вы не хотите добавлять код "test like" в свою схему, это использует запросы 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 

  });

});

Ответ 3

Я реализовал плагин для mongoose, который делает это очень эффективно, используя $near query на двух случайно сгенерированных координатах, используя индекс 2dsphere. Посмотрите здесь: https://github.com/matomesc/mongoose-random.

Ответ 4

Для людей, смотрящих на это во времена асинхронности/ожидания, обещаний и т.д.:

MySchema.statics.random = async function() {
  const count = await this.count();
  const rand = Math.floor(Math.random() * count);
  const randomDoc = await this.findOne().skip(rand);
  return randomDoc;
};

Ответ 5

Более короткое и, возможно, более производительное решение
(мы не перебираем коллекцию один раз, чтобы сосчитать, а второй - чтобы пропустить элементы, но мангуст может сделать это за кадром):

Используйте агрегат и $ sample:

Model.aggregate([{ $sample: { size: 1 } }])