Posts Tagged ‘NoSQL’

BerkeleyDB (BDB) is an embedded database designed for in-application datastores and small devices. At its most basic, it’s a simple key-value store of byte arrays.

Like sqlite, the entire database is self-contained in a series of files, with no process or network port overhead.

Unlike sqlite, it also has good support for managing concurrent transactions and more advanced database features such as live backups and replication.

Querying is also surprisingly advanced. Beyond hashtable style key lookups, the keys themselves are indexable and searchable, and thanks to the secondary index feature, it’s also possible to do complex queries within the data values themselves.

Back in 2009, I was using it extensively on a messaging and workflow project, and I revisted that code when it came time to decide on a datastore for a new, long-running server application designed to run on a Pi.

The first line essentially sets npm in a verbose mode, to let you know what it’s doing as it runs (a tip from the guys at Nodejitsu.com), and the second actually installs the node-mongodb-native module (it seems that the native parser is obsolete, so there is no need to use the --mongodb:native switch in the second line).

So that leaves opening the connection, defining the query or queries, and calling runQuery().

Suppose we have a database consisting of two collections, people and companies, and that we want to search for a given string anywhere among a person’s name, a company’s name, or even a company’s address.

Just like the control flow article, we use a counter in our callback function — doneFn — to check when there are no more queries to run, and once that’s the case, we iterate through the combined list of results and use the document ObjectId to ensure the list of results is unique.

That unique list of results is then passed to the callback function given to search(), i.e., nextFn, which ultimately decides what to do with the combined results.

Each call to runQuery() needs its own db connection, opened like this:

new Db('mydb', new Server(host, port, {}))

because each query will run asynchronously and independently of each other.

It’s also possible to define a single connection, once, before each of the runQuery() calls happen:

var db = new Db('mydb', new Server(host, port, {}));

and just pass the db variable to runQuery(), but then the db.close() line would have to be removed from inside the runQuery() function, and placed inside the doneFn instead.

As for the queries themselves, the beautiful thing about using Javascript and MongoDB together is that any native Javascript object doubles as the query input to MongoDB.