Currently the MongoDB query language has no random-operator (although there is an open feature-request ticket for that).
Update Version 3.2: You can now use the $sample
aggregation operator to obtain a random sample.
collection.aggregate(
[ { $sample: { size: 1 } } ]
)
If you can't or don't want to use it, there are some workarounds, but they aren't pretty.
One is to use db.collection.count()
to get the number of documents in the collection. Then you can select the n
-th document with db.collection.find().skip(n).limit(1)
. But when the collection is large this can take a while, because the whole collection needs to be iterated with a cursor.
Another is to add a field rand
with a random floating-point number between 0.0 and 1.0 to each document when you insert them. Then you can generate another random number r
and do db.collection.find({rand:{$gt:r}}).sort({rand:1}).limit(1)
to get the next greater one. When you have an index on the rand
field, this will be very fast. But the randomness won't be uniformly distributed, because those documents which happen to have a larger gap between them and their predecessor will be picked more frequently. Also, when r
happens to be larger than the largest in the collection, no result will be returned. In that case you should try again with the same number but this time with rand:{$lte:r}
and sort({rand:-1})
. When this doesn't return a document either, the collection is empty (or at least has no documents with a rand
field).
The only corner-case where you can quickly and fairly select a random document is when your collection doesn't change (or at least doesn't change frequently). In that case you can number all the documents with consecutive integers starting with 0, index that field, and find()
for a random number between 0 and your already known number of documents.