Random record from MongoDB
Starting with the 3.2 release of MongoDB, you can get N random docs from a collection using the $sample
aggregation pipeline operator:
// Get one random document from the mycoll collection.db.mycoll.aggregate([{ $sample: { size: 1 } }])
If you want to select the random document(s) from a filtered subset of the collection, prepend a $match
stage to the pipeline:
// Get one random document matching {a: 10} from the mycoll collection.db.mycoll.aggregate([ { $match: { a: 10 } }, { $sample: { size: 1 } }])
As noted in the comments, when size
is greater than 1, there may be duplicates in the returned document sample.
Do a count of all records, generate a random number between 0 and the count, and then do:
db.yourCollection.find().limit(-1).skip(yourRandomNumber).next()
Update for MongoDB 3.2
3.2 introduced $sample to the aggregation pipeline.
There's also a good blog post on putting it into practice.
For older versions (previous answer)
This was actually a feature request: http://jira.mongodb.org/browse/SERVER-533 but it was filed under "Won't fix."
The cookbook has a very good recipe to select a random document out of a collection: http://cookbook.mongodb.org/patterns/random-attribute/
To paraphrase the recipe, you assign random numbers to your documents:
db.docs.save( { key : 1, ..., random : Math.random() } )
Then select a random document:
rand = Math.random()result = db.docs.findOne( { key : 2, random : { $gte : rand } } )if ( result == null ) { result = db.docs.findOne( { key : 2, random : { $lte : rand } } )}
Querying with both $gte
and $lte
is necessary to find the document with a random number nearest rand
.
And of course you'll want to index on the random field:
db.docs.ensureIndex( { key : 1, random :1 } )
If you're already querying against an index, simply drop it, append random: 1
to it, and add it again.