lem
database for time-series data using LevelDB and node.js
installation
$ npm install lem
usage
var lem = ;var level = ; // create a new leveldb - this can also be a sub-levelvar leveldb = ; // create a new lem store using the leveldbvar lemdb = ; // when nodes are indexedlemdb // a live stream from the databaselemdb // nodes are represented by keysvar key = 'myhouse.kitchen.fridge.temperature'; // index a node with some meta datalemdbindexkey 'My Fridge Temp'; // create a recorder which will write data to the nodevar temp = lemdb; // write a value every second
timestamps
When values are written to recorders - they are timestamped. Sometimes - more acurate timestamping (like a GPS source) is used - you can provide the timestamp to the recorder:
var temp = lemdb;
index
You can read the index from any point in the tree - it returns a ReadStream of the keys that have been indexed:
...var through = ; // index a key into the treelemdbindex'cars.red5.speed' 'The speed of the car' { var keysfound = {}; // keys returns a readstream of objects each with a 'key' and 'data' property lemdb
This will log:
Meta: The speed of the car
valuestream
Create a ReadStream of telemetry values for a node - you can specify start and end keys to view windows in time:
// create a range - this can be a 'session' to make meaningful groups within lemvar sessionstart = '04/05/2013 12:34:43';var sessionend = '04/05/2013 12:48:10';var counter = 0;var total = 0; var secs = sessionend - sessionstart / 1000; lemdb
api
var lemdb = lem(leveldb);
Create a new lem database from the provided leveldb. This can be a level-sublevel so you can partition lem into an existing database.
var lem = ;var level = ; var leveldb = ;var lemdb = ;
lemdb.index(path, meta, [done])
Write a node and some meta data to the index.
The index is used to build a tree of key-values that exist without having to traverse the time-stamped keys.
The stream returned can be used to build any kind of data structure you want (list, tree, etc).
The meta data for each node is saved as a string - you can use your own encoding (e.g. JSON).
Create some indexes:
lemdbindex'myhouse.kitchen.fridge.temperature' '{"title":"Fridge Temp","owner":344}';lemdbindex'myhouse.kitchen.thermostat.temperature' '{"title":"Stat Temp","owner":344}';
lemdb.keys(path)
keys returns a ReadStream of all keys in the index beneath the key you provide.
For example - convert the stream into a tree representing all nodes in the kitchen:
...var through = ;var tree = {};lemdb
This outputs:
"fridge.temperature":'{"title":"Fridge Temp","owner":344}' "thermostat.temperature":'{"title":"Stat Temp","owner":344}'
lemdb.recorder(path)
A recorder is used to write time-series data to a node.
You create it with the path of the node:
var recorder = lemdb;
recorder(value, [timestamp], [done])
The recorder itself is a function that you run with a value and optional timestamp and callback.
If no timestamp is provided a default is created:
var timestamp = ;
The callback is run once the value has been committed to disk:
// a function to get an accurate time-stamp from somewhere{ return ...;} // a function to return the current value of an external sensor{ return ...;}var recorder = lemdb; // sample the value every second
events
lemdb.on('index', function(key, meta){})
the 'index' event is emitted when a node is added to the index:
lemdb
lemdb.on('data', function(key, value){})
This is a livestream from leveldb and so contains a full description of the operation:
lemdb
This would log:
type: 'put' key: 'values~cars~red5~speed~1394886656496' value: '85'
license
MIT