MongoDB Experience: Key/Value Store

MongoDB is categorized as a schema-less, schema-free or a document orientated data store. Another category of NoSQL product is the key/value store. It had not dawned on me until a discussion with some of the 10gen employees that MongoDB is also a key/value store, this is just a subset of features.

How would you consider the design of a key/value store? Using the memached model, there are 4 primary attributes to consider:

  • The Key to store/retrieve
  • The Value for the given key
  • An auto expiry of the cached data
  • A key scope enabling multiple namespaces

There are three primary functions:

  • Put a given Key/Value pair
  • Get a given Key
  • Delete a given Key

Let’s explore the options. The first is to create a new collection for each key. That way there is only one row per key,

> use keystore
> var d = new Date();
> var id = "key1";
> var kv = { key: id,val: "Hello World",expires: d}
> db.key1.save(kv);
> db.key1.find();
{ "_id" : ObjectId("4c126095c68fcaf3b0e07a2b"), "key" : "key1", "val" : "Hello World", "expires" : "Fri Jun 11 2010 12:09:51 GMT-0400 (EDT)" }

However when we start loading we run into a problem.

> db.key99999.save({key: "key99999", val: "Hello World", expires: new Date()})
too many namespaces/collections
> show collections;
Fri Jun 11 12:49:02 JS Error: uncaught exception: error: {
	"$err" : "too much key data for sort() with no index.  add an index or specify a smaller limit"
}
> db.stats()
{
	"collections" : 13661,
	"objects" : 26118,
	"dataSize" : 2479352,
	"storageSize" : 93138688,
	"numExtents" : 13665,
	"indexes" : 13053,
	"indexSize" : 106930176,
	"ok" : 1
}

I did read there was a limit on the number of collections at Using a Large Number of Collections.
Also for reference, I look at the underlying data files shows the ^2 increment of data files.

$ ls -lh data/current
total 2.2G
-rw------- 1 rbradfor rbradfor  64M 2010-06-11 12:45 keystore.0
-rw------- 1 rbradfor rbradfor 128M 2010-06-11 12:45 keystore.1
-rw------- 1 rbradfor rbradfor 256M 2010-06-11 12:46 keystore.2
-rw------- 1 rbradfor rbradfor 512M 2010-06-11 12:48 keystore.3
-rw------- 1 rbradfor rbradfor 1.0G 2010-06-11 12:48 keystore.4
-rw------- 1 rbradfor rbradfor  16M 2010-06-11 12:48 keystore.ns
> db.dropDatabase();
{ "dropped" : "keystore.$cmd", "ok" : 1 }

In my next test I’ll repeat by adding the key as a row or document for just one collection.