Извините, но данный вариант хорош лишь в теории. На практике же, попробуйте его исполнить на сравнительно большой коллекции и посмотрите на время выполнения (оно будет очень большим, не смотря на то, что извлекается всего одна запись).
Все дело в том, что сначала выполняется find() без параметров, который возвращает всю коллекцию, и уже после этого работает skip и limit. Время выполнения будет пропорционально размеру коллекции, в то время как выборка одного документа по индексированному полю займет логарифмическое время. У меня на практике было 35мс и 1мс соответственно.
Поэтому единственно правильное решение в данном случае — хранить дополнительное индексированное случайное поле, и делать findOne() по этому полю (в ответе ниже уже дали ссылку на метод)
Ну я это и имел в виду, индекс для _id не ненужен, он просто создается автоматически и существует всегда. Поэтому выборка по _id всегда очень быстрая. _id не индексируется только в особом виде коллекций, которые называются capped collections, но это уже другая история :-)
Все дело в том, что сначала выполняется find() без параметров, который возвращает всю коллекцию, и уже после этого работает skip и limit. Время выполнения будет пропорционально размеру коллекции, в то время как выборка одного документа по индексированному полю займет логарифмическое время. У меня на практике было 35мс и 1мс соответственно.
Поэтому единственно правильное решение в данном случае — хранить дополнительное индексированное случайное поле, и делать findOne() по этому полю (в ответе ниже уже дали ссылку на метод)