Find file History
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Failed to load latest commit information.



mongo is a scalable, high-performance, open source, schema-free, document-oriented database..

This is a common lisp interface that allows you to work with a mongo document database. This is not a driver (yet) as specified in the mongo documents; There is still some functionality I need to implement.

Various features are missing such as serialization of binary data and code, authentication, gridfs among other things.

In its current state cl-mongo provides the ability to insert, update and delete documents. It also supports indexing.

I developed this using sbcl. I didn't rely on any sbcl extenxions so I expect this to run under other lisps as well.


Version 0.1.1

This version is basically an alpha release. Many features are and testing has not been tested extensively.


Use asdf to install cl-mongo.

A sample session

This connects to the test database on the local mongo server listening on its default port.

(use-package :cl-mongo)
(db.use "test")

Insert a key-value pair as the first document into collection "foo".

(db.insert "foo" (kv "document" "one") )

Pretty-print the documents returned by the find command. iter will ensure that the cursor is fully iterated over.

(pp (iter (db.find "foo" 'all)))`

    "_id" -> objectid(4B5CF28970DFF196A75FE1F0)
    "document"  ->  one

Create a document. A document is collection of key-value pairs and a unique identifier called "_id".

(defvar *DOC* (make-document))

Add various elements to the document.

   (add-element "tag" "key" *DOC*)`


   tag  -> key 

(add-element "array" (list 1 2 3 "hello") *DOC*)


tag  -> key 
 array  -> NIL 

Insert document into the database.

(db.insert "foo" *DOC*)

Print the current contents.

   (pp (iter (db.find "foo" 'all)))

   "_id" -> objectid(4B5CF28970DFF196A75FE1F0)
   "document"  ->  one

   "_id" -> objectid(8B508D5CBB5D451D961F046D)
   "array"  -> [ 1, 2, 3, hello,]
   "tag"  ->  key

Bind variable *DOC* to the second document returned by the find command, add an other element and save back to the collection.

  (defvar *DOC* (cadr (docs (db.find "foo" 'all))))`
  (add-element "tags" (list 'good 'bad 'ugly) *DOC*)
  ( "foo" *DOC*)
  (pp (db.find "foo" 'all))

"_id" -> objectid(4B5CF28970DFF196A75FE1F0)
    "document"  ->  one

    "_id" -> objectid(8B508D5CBB5D451D961F046D)
    "tags"  -> [ GOOD, BAD, UGLY,]
    "tag"  ->  key
    "array"  -> [ 1, 2, 3, hello,]

Check the status of the server.

  (db.use "admin")
  (nd ( 'serverstatus))

    "ok"  ->  1.0d0
  "mem"  -> 
    "mapped"  ->  80
    "virtual"  ->  177
        "resident"  ->  3
    "globalLock"  -> 
      "ratio"  ->  4.644753171959394d-5
      "lockTime"  ->  6493354.0d0
    "totalTime"  ->  1.39799764586d11
    "uptime"  ->  139799.0d0

What's missing

At least the following is missing :

  • Request id/ Response id are left 0 in the header.
  • Serialization of binary data.
  • Serialization of regular expressions.
  • Serialization of code scope.
  • Advanced queries like min/max queries, group by, snapshot support.
  • Aggregation except for distinct and group by.
  • Authentication
  • GridFS
  • ......


CL-MONGO - cl-mongo



The code comes with a MIT-style license so you can basically do with it whatever you want.

Download shortcut:



  1. Download
  2. The CL-MONGO dictionary
    1. add-element
    2. close-all-connections
    3. cwd
    4. date-time
    5. db.collections
    6. db.collections
    7. db.count
    8. db.delete
    9. db.ensure-index
    10. db.eval
    11. db.find
    12. db.indexes
    13. db.indexes
    14. db.insert
    15. db.iter
    19. db.stop
    20. db.update
    21. db.use
    22. docs
    23. document
    24. gendoc
    25. get-element
    26. ht->document
    27. iter
    28. kv
    29. make-document
    30. mongo
    31. mongo
    32. nd
    33. now
    34. nwd
    35. pp
    36. rm
    37. rm-element
    38. time-zone
  3. Acknowledgements



CL-MONGO together with this documentation can be downloaded from The current version is 0.1.0.


The CL-MONGO dictionary

[Generic function]
add-element key value document => result

add element with key and value to a document

close-all-connections => result

Close all connections in the global connection list.

cwd &key mongo => result

Show the current database.

date-time second minute hour day month year &optional time-zone => result

Generate a time stamp the mongo/bson protocol understands.

[Generic function]
db.collections &key mongo => result

db.collections &key mongo => result

Show all the collections in the current database.

[Generic function]
db.count collection selector &key mongo => result

Count all the collections satifying the criterion set by the selector. 'all can be used to return a count of all the documents in the collection.

[Generic function]
db.delete collection object &key mongo => result

Delete a document from a collection. The *document* field is used to identify the document to be deleted. You can enter a list of documents. In that the server will be contacted to delete each one of these. It may be more efficient to run a delete script on he server side.

[Generic function]
db.ensure-index collection keys &key unique mongo asc => result

Create an index specified by the keys in a collection

[Generic function]
db.eval code &rest rest => result

run javascript code server side

[Generic function]
db.find collection kv &key selector limit skip options mongo => result

Find documents in the collection using the selector specified by kv. Methods take two keywords. ':limit' sets the maximum number of documents returned. The default is 1. ':skip' sets the number of documents to skip in this query. It's default is 0. Since the default value of the limit is one, db.find by default is the equivalant of *findOne* in the mongo documentation.

[Generic function]
db.indexes &key mongo => result

db.indexes &key mongo => result

Return all indexes in the database.

[Generic function]
db.insert collection document &key mongo => result

Insert a document in a collection. A document is typically generated by `(make-document)`, but it can also be a hash table, a key-value pair or kv list (see the kv functions).

[Generic function]
db.iter result &key limit mongo => result

next document iteration

[Generic function] collection cursor-id &key limit mongo => result

Executes the next call on the iterator identified by cursor-id.

[Generic function] cmd &key arg mongo index collection => result

Run a database command on the server. See the mongo documentation for a list of commands. For most commands you can just uses the key-value shown in the mongo documentation.

[Generic function] collection document &key mongo => result

Save a document to the collection. If the document has a unique `_id` value (i.e. if it's generated by `(make-document)` ) it will be 'upserted' (that is: it will be inserted if the document doesn't exist). If the document a hash table or a kv set, it will be inserted. In other words this a a helper-function build around *db.insert* and *db.update*.

[Generic function]
db.stop cursor &key mongo => result

Stop iterating and clean up the iterator on the server by making a server call.

[Generic function]
db.update collection selector new-document &key mongo upsert multi => result

In a collection update the document(s) identified by the selector statement. This method has two keywords. ':upsert' : If t insert the document if the document cannot be found in the collection. ':multi' : Update all documents identified by the selector.

[Generic function]
db.use db &key host port => result

Use a database on the mongo server. Opens a connection if one isn't already established. (db.use -) can be used to go to a previosuly visited database, similar to cd -.

docs result => result

Stop the iterator (if any) and return the list of documents returned by the query. Typical ue would be in conjunction with db.find like so (docs (iter (db.find 'foo' 'll)))

[Standard class]

document Document class. A document consists of key/value pairs stored in a internal hash table plus an internally generated unique id. Accessors are : 'elements' which returns the internal hash table; '_id' which returns the unique id and '_local_id' which if true means that the document was generated by the client (as opposed to having been read from the server).

gendoc target => result

[Generic function]
get-element key document => result

Get an element identified by key from the document.

ht->document ht => result

Convert a hash-table to a document.

iter result &key mongo max-per-call => result

Exhaustively iterate through a query. The maximum number of responses per query can be specified using the max-per-call keyword.

[Generic function]
kv a b &rest rest => result

This a helper function for key-value pairs and sets of key-value pairs. In a key-value pair like (kv key value) the key has to be a string and the value something which is serializable. key-value pairs can be combined using kv as well : (kv (kv key1 val1) (kv key2 val2)). This combination of key-value pairs is equivalent to a document without a unique id. The server will assign a unique is if a list of key-value pairs is saved.

make-document &key oid => result

Constructor. key ':oid' is a user supplied unique id. An internal id will be generated if none is supplied.

[Standard class]

Encapsulates the connection to the mongo database. Each connection is a added to a global list of connections.

[Generic function]
mongo &key index host port => result

mongo connection

nd result &key stream => result

Pretty-print for non-document responses, like the response to a database command.

now => result

Return the current date and time in bson format.

nwd => result

Show the database set by the `(db.use -)` command

[Generic function]
pp result &key nd stream => result

Pretty-print the results returned from a query. To be used on the repl. This will format each server reply as if it were a document. This is obviously ok in mosty cases. See nd for an alternative.

rm result &key mongo => result

Delete all the documents returned by a query. This is not an efficient way of deleting documents as it invloves multiple trips to the server. Mongo allows for execution of java-script on the server side, which provides an alternative. Typical use would be (rm (iter (db.find 'foo' (kv 'key' 1)))), which deletes all documents in foo, with field key equal to 1.

[Generic function]
rm-element key document => result

Remove element identified by key from a document

time-zone => result

Set the time zone appropriate for the current environment.



This documentation was prepared with DOCUMENTATION-TEMPLATE.

$Header: /usr/local/cvsrep/documentation-template/output.lisp,v 1.14 2008/05/29 08:23:37 edi Exp $