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.