Pages

Wednesday, October 23, 2013

Get Random Documents from MongoDB

While finalizing my first draft of nodecards, I stumbled on retrieving random documents from MongoDB. Nodecards is a small open source project which I use to try out some new technologies. It is a simple Flashcard application, written in node.js. It is kinda quick'n'dirty coded stuff, so don’t expect clean lines of code, yet. Because it was not so easy and I am not really sure that I have taken the right way I want to present you my implementation of retrieving random documents from MongoDB.

Get random within the range of a collection


To get the random document i just call count() at the collection.
After that I used skip() within the find to skip a number of documents. The skip is based on Math.random() and the previous estimated max range. Moreover I added a limit(1) to retrieve just one document. In a nutshell: My way to get random documents is by skipping documents based on a random number and limit the size to one. If you have some better and more efficient ways to do, please let me know.

Get random within a custom scope


Furthermore I had the idea to reduce the number on documents by adding a specific user defined condition. I passed in a max value that has been chosen by a user. Based on that max value I count how much elements are in the db.coll.correct array and retrieve only documents where the number of containing elements is lower than the max value. Cheers, Frank

3 comments:

  1. The Mongo cookbook lists a more advanced technique using a random number stored along with each document - http://cookbook.mongodb.org/patterns/random-attribute/

    ReplyDelete
  2. Tried this way, the 'mongo cookbook' way, and a couple of others - they are either clumsy, slow, and/or (more often) return the same results too often (which is actually worse than clumsy and slow put together). THE BEST WAY so far is to store random X,Y numbers in mongo geospatial format, then do $near lookup against random G, H numbers - very clever, super fast, elegant, also works against real GPS coordinates.

    ReplyDelete