Node.js + LevelDB

This article is based on a recent NodeUp podcast dedicated to LevelDB, I recommend listening to it.

I have played around a bit with Level, and I’ve been really impressed by it’s speed, ease and simplicity. You should give it a go.

LevelDB was developed by Jeffrey Dean and Sanjay Ghemawat at Google. It is an ‘in process’ sorted key-value pair database. It persists data to the file system. This means that it works in a similar way to SQLite, in that the database is private to your process. Level is great if you want to create your own database (Riak for example) or you want to create a portable app that persists data itself (like Chrome).

Node has some good support for LevelDB with two packages, LevelDown for low-level bindings to the LevelDB DLL, and LevelUp, a higher level abstraction (i.e. easier to use) over LevelDown.

Getting started

To get started, just install LevelUp.

$> npm install levelup

In your node app, you can now start using the database like this:

var level = require('levelup');
var db = level('./DatabaseDirectory');

You can then read, write and delete key/value in the database like this:

db.put('key', 'value');
db.get('key', function(error, data){ //data == 'value' }); 
db.del('key');

Iterating over a range of keys

What’s more interesting is you can iterate over the keys like this:

var options = {start:'key1', end: 'key9'};
var readStream = db.createReadStream(options);
readStream.on('data', function (data) {
  // each key/value is returned as a 'data' event
  console.log(data.key + ' = ' + data.value);
});

To stop reading records, just call destroy on the stream, for example if you’re looking for a particular value (this is a bad idea):

var readStream = db.createReadStream({});
readStream.on('data', function (data) {
  if (data.value == 'foo'){
    readStream.destroy();
  }
});

Using the options, you can iterate forwards/backwards, retrieve just the keys or values, and limit the number of keys returned.

Multiple tables?

There is only one table in LevelDB. To store different types of data you need to express a hierarchy in the key names. As the keys in level are stored in unicode order, the ‘~’ (tilde) character seems to be a good choice for separating parts of a key, like this:

customers~customer1~orders~

You can then retrieve all orders for customer1 using this range (use this for the options object in the previous example):

{start:'customers~customer1~', end: 'customers~customer1~~'};

The double tilde as the end of the range ensures you get all the orders for ‘customer1’.

More?

There’s a few more bits of Level, including transactions and an event system etc… You can find out more on the GitHub readme.

Advertisements