You are on page 1of 10

Getting Started With CouchDB in Node.

js
In this tutorial I’m going to walk you through how to get started with CouchDB in Node.js. But
first here’s some background on what CouchDB is. CouchDB is a NoSQL database from the
Apache Foundation. Just like any other NoSQL database out there. It uses JSON to store data and
it deals with separate documents instead of tables and fields.

Installing CouchDB

You can install CouchDB by executing the following command:

sudo apt-get install couchdb

Once that’s done you can test if its successfully installed by accessing http://localhost:5984/
from your browser. You’re good to go if it returns a response similar to the following:

{"couchdb":"Welcome","uuid":"0eb12dd741b22a919c8701dd6dc14087","version":"1.5
.0","vendor":{"version":"14.04","name":"Ubuntu"}}

Futon

If you’re from the RDBMS land. You might be familiar with Phpmyadmin. In CouchDB Futon is
the equivalent of Phpmyadmin. It allows you to manage your CouchDB databases with ease. In
case you’re wondering what Futon means, its basically a Japanese word. Futon is a traditional
japanese bedding.

Ok enough with the trivia. You can access Futon by going to http://localhost:5984/_utils/.
It should show you something similar to the following:
The first thing you need to do is to configure futon so that it has an admin user. Because by default,
every user who has access to it have admin privileges. It can only be accessed from the local
computer so this isn’t really a security issue. Not unless a hacker gets to access the server. You
can setup an admin by going into the configuration page. Just click ‘Configuration’ under the tools
menu to get there. Next click on the ‘setup admin’ link found at the bottom right corner. This
should open up a modal that asks you to enter the username and password that you can use for
logging in as admin.

Just enter your desired username and password and then click ‘create’ to create the admin. You
can now login as an admin by clicking on the ‘login’ link. Non-admin users will only now have
read privileges once you have setup your first admin user.

With Futon you can create a new database, add documents, update documents, delete documents
and delete a database. Using Futon is pretty straightforward so I’m just going to leave it to you to
explore it.

Creating a Database

You can create a new database via Futon. From the Futon index page, click on the ‘create database’
link to create a new database. This will create a new database where you can add new documents.

Adding New Documents

You can add new documents by making a curl request to port 5984 of your localhost. Here’s an
example:

curl -X POST http://127.0.0.1:5984/test_db/ -d '{"name": "Ash Ketchum", "age":


10, "type": "trainer"}' -H "Content-Type: application/json"

Here’s a breakdown of the options we have passed to curl:

• -X POST http://127.0.0.1:5984/test/ – the -X option is used to specify the type of


request and the host. In this case the host is the URL in which CouchDB is running. And
the type of request is POST
• -d '{"name": "Ash Ketchum", "age": 10, "type": "trainer"}' – -d is used for
specifying the data that you want to submit. In this case were using a JSON string to
represent the data. Note that there are no fields that are required by CouchDB. But its
helpful to specify a type field so that we can easily query documents later on based on
their type.
• -H "Content-Type: application/json" – -H is used for specifying the header type.

Executing the command above will return something similar to the following:
{
"ok":true,
"id":"cc6b37f1e6b2215f2a5ccac38c000a43",
"rev":"1-61280846062dcdb986c5a6c4aa9aaf03"
}

Usually this is the status of the request (ok), the id assigned to the document (id), and the revision
number (rev).

Retrieving Documents

You can retrieve all documents from a specific database by using a GET request:

curl -X GET http://127.0.0.1:5984/test_db/_all_docs

This returns the following:

{
"total_rows":1,
"offset":0,
"rows":[
{
"id":"cc6b37f1e6b2215f2a5ccac38c000a43",
"key":"cc6b37f1e6b2215f2a5ccac38c000a43",
"value":{
"rev":"1-61280846062dcdb986c5a6c4aa9aaf03"
}
}
]
}

Note that this only returns the id, key and value of the document and not the actual contents of the
documents. If you also need to return the contents, just add the include_docs as a query parameter
and set its value to true:

curl -X GET http://127.0.0.1:5984/test_db/_all_docs?include_docs=true

If you want to retrieve a specific document, use the document id:

curl -X GET http://127.0.0.1:5984/test_db/cc6b37f1e6b2215f2a5ccac38c000a43

If you want to retrieve a specific revision, you can supply rev as a query parameter and then use
the revision id as the value.

curl -X GET
http://127.0.0.1:5984/test/cc6b37f1e6b2215f2a5ccac38c000a43?rev=1-
61280846062dcdb986c5a6c4aa9aaf03
Updating Documents

You can update documents by using the document id and the revision id. All you have to do is
make a PUT request to the database that you want to update and add the document id as a path. And
then supply the updated data along with the revision that you want to update:

curl -X PUT http://127.0.0.1:5984/test_db/cc6b37f1e6b2215f2a5ccac38c000a43 -d


'{"_rev": "1-61280846062dcdb986c5a6c4aa9aaf03", "name": "Ash Ketchum", "age":
12, "type": "trainer"}' -H "Content-Type: application/json"

It should return something similar to the following if the update was successful:

{
"ok":true,
"id":"cc6b37f1e6b2215f2a5ccac38c000a43",
"rev":"2-0023f19d7d3097468a8eeec014018840"
}

Revisions is an important feature that comes with CouchDB. Its like a built-in version control for
each document. You can always go back to a previous version of a specific document as long as
you haven’t deleted it.

Deleting Documents

You can delete a document by using the same path as updating documents or when you’re
retrieving them. The only difference is you need to use a DELETE request and supply the revision
id as a query parameter:

curl -X DELETE
http://127.0.0.1:5984/test_db/cc6b37f1e6b2215f2a5ccac38c000a43?rev=2-
0023f19d7d3097468a8eeec014018840

This deletes the second revision of the document. If you check the document from Futon, you will
no longer see it there. But you will still be able to get a specific revision which haven’t been deleted
if you supply the previous revision id in the request for getting a specific document:

curl -X GET
http://127.0.0.1:5984/test_db/cc6b37f1e6b2215f2a5ccac38c000a43?rev=1-
61280846062dcdb986c5a6c4aa9aaf03

Backup and Restore

Unlike Phpmyadmin, Futon doesn’t come with backup and restore capabilities. Good thing we
have this awesome guy who created a backup and restore utility for CouchDB. Just download the
couchdb-backup.sh file from the Github repo and place it somewhere in your computer.
To backup a specific database, just use the bash command and supply the filename of the backup
utility. You supply the -b option if you want to backup and -r if you want to restore. -H is the
host, if you don’t supply the port it uses 5984 by default. -d is the name of the database. -f is the
filename of the backup file that will be created. -u is the admin username that you use for logging
in to Futon. And -p is the password:

bash couchdb-backup.sh -b -H 127.0.0.1 -d test_db -f test_db.json -u


your_username -p your_password

To restore the backup, just supply the -r option instead of -b:

bash couchdb-backup.sh -r -H 127.0.0.1 -d test_db -f test_db.json -u


your_username -p your_password

Views

Views are used to query the database for a specific data. If you’re coming from the RDBMS land,
you usually select specific data using the SELECT command. And then you use WHERE to get what
you want. Once you’re done, you call it a day. With CouchDB its different. Because it doesn’t
come with functions that allows you to select specific data easily. In CouchDB we need to use
views. A view is basically just a JavaScript function that emits the documents that you need.

Before we move on with working with views, you can add the following document to your
CouchDB database if you want to follow along:

{"new_edits":false,"docs":[
{"_id":"cc6b37f1e6b2215f2a5ccac38c000e58","_rev":"1-
cbc1dd4e0dd53b3f9770bb8edc30ae33","name":"pikachu","type":"electric","trainer
":"ash","gender":"m"},
{"_id":"cc6b37f1e6b2215f2a5ccac38c001e2c","_rev":"2-
fbe6131ea1248b83301900a5954dec6d","name":"squirtle","type":"water","trainer":
"ash","gender":"m"},
{"_id":"cc6b37f1e6b2215f2a5ccac38c0020d9","_rev":"1-
8f98424393470486d60cf5fff00f33d3","name":"starmie","type":"water","trainer":"
misty","gender":"f"},
{"_id":"cc6b37f1e6b2215f2a5ccac38c00215e","_rev":"1-
aac04234d60216760bd9e3f89fa602e9","name":"geodude","type":"rock","trainer":"b
rock","gender":"m"},
{"_id":"cc6b37f1e6b2215f2a5ccac38c0030b4","_rev":"1-
280586eb35fc3bde31f88ec9913f3dcb","name":"onix","type":"rock","trainer":"broc
k","gender":"m"}
]}

What you see above is a backup file which you can restore by using the backup and restore utility
which I introduced earlier.
Creating a View

You can create a view by selecting your database from Futon. From there, look for the view
dropdown box and then select ‘temporary view…’. This allows you to test and create a view. Enter
the following in the view code box:

function(doc) {
emit(doc.type, null);
}

Click on ‘run’ to run it. This will list all of the documents in the database using the type field as
its key. We have set the value to null because we don’t need it. The value can be set to doc and
then the value that’s returned will be the actual contents of the document. You can do that but its
not really good practice since it consumes a lot of memory. Once you see some output you can
now click on ‘save as’ and then supply the name of the design document and the view name. You
can name those with any name you want but its good practice to give the design document a name
which represents the type of document. In this case its ‘pokemon’. And the view name would be
the key that you use. Some folks usually prefix it with by_. I also prefer it so I’ll name the view
‘by_type’. Click on ‘save’ once you’re done giving the names.

Here’s how you can use the view:

curl
"http://127.0.0.1:5984/test_db/_design/pokemon/_view/by_type?key=%22water%22"

Breaking it down, the first part of the URL is the host where CouchDB is running:

http://127.0.0.1:5984

Next is the database:

test_db

And then you specify the name of the design document by supplying _design followed by the
name of the design document:

_design/pokemon

Next you also need to specify the view:

_view/by_type

And then lastly, your query:

key=%22water%22"
Note that you need to supply a URL encoded query. %22 represents double-quotes so were
wrapping the actual query with %22 instead of double-quotes. Executing it would return the
following. Basically the same as what you seen in Futon but this time its filtered according to the
value you supplied as the key:

{
"total_rows":5,
"offset":3,
"rows":[
{
"id":"cc6b37f1e6b2215f2a5ccac38c001e2c",
"key":"water",
"value":null
},
{
"id":"cc6b37f1e6b2215f2a5ccac38c0020d9",
"key":"water",
"value":null
}
]
}

So the idea of views is that you have to emit the value for the field that you want to perform your
query on. In this case we have emitted the type field.

Working with Node.js

You can work with CouchDB using the Nano package. You can install it in your project by
executing the following command:

npm install nano --save

To use nano, create a new JavaScript file and name it app.js. Then you can connect to CouchDB
by adding the following code:

var nano = require('nano')('http://localhost:5984');

If you already have a specific database to work with, you can connect to it by using the db.use
method and then supply the name of the database as the argument:

var test_db = nano.db.use('test_db');

Creating New Documents

You can create new documents by using the insert method:


var data = {
name: 'pikachu',
skills: ['thunder bolt', 'iron tail', 'quick attack', 'mega punch'],
type: 'electric'
};

test_db.insert(data, 'unique_id', function(err, body){


if(!err){
//awesome
}
});

The insert method takes up the data that you want to save as its first argument, the id as its second
argument and the third is the function that will be called once it gets a response. Note that the id is
optional, so you can choose to supply a value or not. If you didn’t supply a value for it then
CouchDB will automatically generate a unique id for you.

Retrieving Documents

Views are still utilized when retrieving specific documents from CouchDB in Nano. The view
method is used for specifying which view you want to use. This method takes the name of the
design document as its first argument, the name of the view as its second and then the query
parameters that you want to pass in as the third argument. The fourth argument is the function that
you want to execute once a response has been received:

var type = 'water';


db.view('pokemon', 'by_type', {'key': type, 'include_docs': true},
function(err, body){

if(!err){
var rows = body.rows; //the rows returned
}

}
);

Updating Documents

Nano doesn’t come with an update method by default. That is why we need to define a custom
method that would do it for us. Declare the following near the top of your app.js file, right after
your database connection code.

test_db.update = function(obj, key, callback){


var db = this;
db.get(key, function (error, existing){
if(!error) obj._rev = existing._rev;
db.insert(obj, key, callback);
});
}
You can then use the update method in your code:

db.update(doc, doc_id, function(err, res){


if(!err){
//document has been updated
}

});

Note that you need the id of the document when performing an update. That’s why you first need
to create a view that would emit a unique field as the key and the document id as the value. In this
case the unique field is the name. Each Pokemon has a unique name so this works:

function(doc) {
emit(doc.name, doc._id);
}

Just give this view a design name of ‘pokemon’ and a name of ‘by_name’. And then you can use
this view to update a Pokemon by name. All you have to do is call the update method once you
have retrieved the id and the current document.

var name = 'pikachu';


db.view('pokemon', 'by_name', {'key': name, 'include_docs': true},
function(select_err, select_body){
if(!select_err){
var doc_id = select_body.rows[0].id;
var doc = select_body.rows[0].doc;

//do your updates here


doc.age = 99; //you can add new fields or update existing ones

db.update(doc, doc_id, function(err, res){


if(!err){
//document has been updated
}

});
}
});

Deleting Documents

If you no longer want a specific document and you need to delete it, you can use the destroy
method. This takes up the id of the document as the first argument, the revision id of the revision
that you want to delete as the second argument, and then the function that you want to execute
once you get a response:
test_db.destroy(doc_id, revision_id, function(err, body) {
if(!err){
//done deleting
}
});

You might also like