MongoDB Driver Requirements


This legacy documentation does not necessarily reflect the current practices in MongoDB driver implementation, but may be useful for historical purposes. See the MongoDB Meta Driver for the current documentation of MongoDB driver implementation.

This is a high-level list of features that a driver for MongoDB might provide. We attempt to group those features by priority. This list should be taken with a grain of salt, and probably used more for inspiration than as law that must be adhered to. A great way to learn about implementing a driver is by reading the source code of any of the existing drivers, especially the ones listed as “mongodb.org supported”.

High Priority

  • BSON serialization/deserialization
  • full cursor support (e.g. support OP_GET_MORE operation)
  • close exhausted cursors via OP_KILL_CURSORS
  • support for running database commands
  • handle query errors
  • convert all strings to UTF-8 (part of proper support for BSON)
  • hint(), explain(), count(), $where
  • database profiling: set/get profiling level, get profiling info
  • advanced connection management (replica sets, slaveOkay)
  • automatic reconnection

Medium Priority

  • validate a collection in a database
  • buffer pooling
  • Tailable cursor support

A driver should be able to connect to a single server. By default this must be localhost:27017, and must also allow the server to be specified by hostname and port.

Mongo m = new Mongo();   // go to localhost, default port

Mongo m = new Mongo(String host, int port);

How the driver does this is up to the driver - make it idiomatic. However, a driver should make it explicit and clear what is going on.

Replica Sets

A driver must be able to support “Replica-Set” configurations, where multiple mongod servers are specified, and configured for hot-failover.

The driver should determine which of the nodes is the current master, and send all operations to that server. In the event of an error, either socket error or a “not a master” error, the driver must restart the determination process.

Cluster Mode Connect to master in master-slave cluster

ServerCluster sc = new ServerCluster(INETAddr...); // again, give one and discover?
Mongo m = new Mongo(sc);

## Connect to slave in read-only mode in master-slave cluster

ServerCluster sc = new ServerCluster(INETAddr...); // again, give one and discover?
Mongo m = new Mongo(sc);

or maybe make it like *Default/Simple* w/ a flag?

Other than that, we need a way to get a DB object:

Mongo m = new Mongo();

DB db = m.getDB(name);

And a list of db names (useful for tools...) :

List<String> getDBNameList();

Database Object

Simple operations on a database object :

 *  get name of database
String    dbName = db.getName();

 * Get a list of all the collection names in this database
List<String> cols = db.getCollectionNames();

 * get a collection object.  Can optionally create it if it
 *  doesn't exist, or just  be strict.  (XJDM has strictness as an option)
Collection coll = db.getCollection(string);

 * Create a collection w/ optional options.  Can fault
 * if the collection exists, or can just return it if it already does
Collection coll = db.createCollection( string);
Collection coll = db.createCollection( string, options);

 * Drop a collection by its name or by collection object.
 * Driver could invalidate any outstanding Collection objects
 * for that collection, or just hope for the best.
boolean  b  = db.dropCollection(name);
boolean  b  = db.dropCollection(Collection);

 * Execute a command on the database, returning the
 * BSON doc with the results
Document d = db.executeCommand(command);

 * Close the [logical] database
void  db.close();

 * Erase / drop an entire database
bool dropDatabase(dbname)

Database Administration

These methods have to do with database metadata: profiling levels and collection validation. Each admin object is associated with a database. These methods could either be built into the Database class or provided in a separate Admin class whose instances are only available from a database instance.

/* get an admin object from a database object. */
Admin admin = db.getAdmin();

 * Get profiling level. Returns one of the strings "off", "slowOnly", or
 * "all". Note that the database returns an integer. This method could
 * return an int or an enum instead --- in Ruby, for example, we return
 * symbols.
String profilingLevel = admin.getProfilingLevel();

 * Set profiling level. Takes whatever getProfilingLevel() returns.

 * Retrieves the database's profiling info.
Document profilingInfo = admin.getProfilingInfo();

 * Returns true if collection is valid; raises an exception if not.
boolean admin.validateCollection(collectionName);


Basic Ops

 *   full query capabilities - limit, skip, returned fields, sort, etc
Cursor        find(...);

void          insert(...) // insert one or more objects into the collection, local variants on args
void          remove(query) // remove objects that match the query
void          update(selector, modifier)  // modify all objects that match selector w/ modifier object
void          updateFirst(selector, object)   // replace first object that match selector w/ specified object
void          upsert(selector, object)   // replace first object that matches, or insert
long          getCount();
long          getCount(query);

Index Operations

void          createIndex( index_info)
void          dropIndex(name)
void          dropIndexes()
List<info>    getIndexInformation()

Misc Operations

document      explain(query)
options       getOptions();
string        getName();
void          close();

Cursor Object

document      getNextDocument()
iterator      getIterator()  // again, local to language
bool          hasMore()
void          close()