Multi-field sorting in MongoDB using cl-mongo

After 15 years of occasional SQL work and a couple years of seeing NoSQL all over the place, I bit the bullet and decided to convert one projects over from PostGreSQL to MongoDB.

The project was a simple UCW web app written in Common Lisp and parked at

Originally, the entire database was loaded into ram as a simple set of linked lists. As other projects started consuming memory in the virtual machine, I decided to move the database into postgres using the postmodern library. The postmodern/postgres version works great and is quick, the only reason for the migration and dbi rewrite was to learn mongo and do some “fun” coding.

Most of the translation was very straight forward. I wrote a little iterator function to migrate the data to the new backing store right in the live app. The app is almost entire the ‘r’ part of CRUD and the various read/get functions were trivial and became smaller and cleaner.

There was a small snag, however!

In the ‘all’ page I made to help crawlers navigate, the SQL had an “order by db,id”. The first Mongo approach I tried did no sorting at all and worked ok, but the lack of order in the output… annoyed me.

The cl-mongo documentation at has a handy db.sort macro, but the input is a “field to sort on” in the :field &keyword. I set the “id” field and gave it a whack and it behaved as expected… intermixing the databases.

The trick is to ignore #’db.sort macro and add the order-by stuff to #’db.find as part of the query.

The following code will return all results and sort by db and id. (“:use :cl-mongo” is assumed)
(db.find "adage" (kv (kv "query" (kv nil nil)) (kv "orderby" (kv (kv "db" 1) (kv "id" 1)))) :limit 0)

That’s all there is to multiple field sorting in MongoDB using the cl-mongo library.

I hope that little detail helps!

Are you doing anything cool with cl-mongo or need some help? Leave a comment or shoot me an email!

Last modified on February 3, 2015. This entry was posted in LISP and tagged , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published.