CouchApp: how to use views map/reduce


There is a JavaScript embedded in CouchDB: the one that is used in Futon. Lets see how to use it from your CouchApp for executing map/reduce views. This post is a follow on of this one.

Executing a view using jquery.couchdb.js

Background

Invoking a view is done by using:

db.view("design/view", {
    success:function (data) {
        // Got response from CouchDB
        // Process data
        // and then return retrieved data
    },
    error  :function (status) {
        // Error function...
    }
});

Where design is the CouchDB design document storing the view (view).

Using a key in a map function

Lets consider a CouchDB database with cities and states from USA stored in documents with the following structure:

{
   "_id": "0254D19B-7360-459E-A9F2-715E36AD1822",
   "_rev": "1-d6c3ca78003b4116ecef930d538b2d94",
   "type": "cities",
   "city": "Pasadena",
   "state": "California"
},
{
   "_id": "05C7AD05-0CC6-4C6E-A21B-E4C8344C242A",
   "_rev": "1-e0a64cd86be76166d3b1592376b8c23c",
   "type": "cities",
   "city": "Lakewood",
   "state": "Colorado"
}

I.e., Documents with field type value cities that allows me to isolate records containing the pairs (city – state) from others stored in the same database; and the the name of the city and the state itself.

Then I have defined the following map function:

function(doc) {
    if (doc.type==="cities") emit(doc.state, doc.city );
}

That emits every document of type cities. These emitted records will have as key the name of the state and as value, the name of the city.

If I execute the view using:

db.view("post20/getCities", {
    success:function (data) {
        console.log(JSON.stringify(data));
    },
    error  :function (status) {
        console.log(status);
    }
});

Where post20 is the design document and getCities is the name of the view.

I get something like:

{
    "total_rows": 285, 
    "offset": 0,
    "rows": [
        {"id":"34716A25-2D33-43F7-BDA2-CBC063BC04A4", "key":"Alabama", "value":"Mobile"},
        {"id":"4F5D34B0-8F24-4C84-98D3-6F104EB19C42", "key":"Alabama", "value":"Montgomery"},
        {"id":"B3BB27B0-9D6E-4776-A685-67378E9198A3", "key":"Alabama", "value":"Birmingham"},
        {"id":"91B00C11-6648-4E15-83F2-957561ACE157", "key":"Alaska", "value":"Anchorage"},
        {"id":"212EA2DA-40C3-4443-AFB7-91366891D3D5", "key":"Arizona", "value":"Tucson"},
        {"id":"7132A69F-B1CE-4AB6-ABF8-22EC6745C35D", "key":"Arizona", "value":"Phoenix"},
        {"id":"9938B89F-E119-47AA-9186-F15BDEF557E1", "key":"Arizona", "value":"Surprise"},
        {"id":"A2E9C9F5-033F-454D-8B54-3A303F2E13C2", "key":"Arizona", "value":"Peoria"},
        {"id":"BFD01743-2297-47B1-B997-4B63B9BF4213", "key":"Arizona", "value":"Mesa"},
        ...
}

But, I want to choose only the cities from California then I have to set California as key (and that’s why I defined the map function that emits the state as key. To send the key to CouchDB I have to say:

db.view("post20/getCities", {
    success:function (data) {
        console.log(JSON.stringify(data));
    },
    error  :function (status) {
        console.log(status);
    },
    key    :"California"
});

and I get as result:

{
    "total_rows":285,
    "offset"    :16,
    "rows"      :[
        {"id":"0254D19B-7360-459E-A9F2-715E36AD1822", "key":"California", "value":"Pasadena"},
        {"id":"07A64E55-2AB1-4AA2-81E8-3D1D54508A26", "key":"California", "value":"Vallejo"},
        {"id":"07CB593A-8F8A-4100-B650-BB949775EBA4", "key":"California", "value":"Ontario"},
        {"id":"0884A3CD-2D54-4B4C-9492-4BCF168F04DA", "key":"California", "value":"Salinas"},
        {"id":"0C835A0A-6109-4986-904B-5C6102D86EB4", "key":"California", "value":"San Buenaventura (Ventura)"},
        {"id":"10687A90-F40B-4154-BF46-A1D976C8E800", "key":"California", "value":"Fresno"},
        ...
    ]
}

Neat!

What about if I want to retrieve the list of cities of Alaska and Wisconsin?

db.view("post20/getCities", {
    success:function (data) {
        console.log(JSON.stringify(data));
    },
    error  :function (status) {
        console.log(status);
    },
    keys   :[ "Alaska", "Wisconsin" ]
});

and I get:

{"total_rows":285, "offset":4, "rows":[
    {"id":"91B00C11-6648-4E15-83F2-957561ACE157", "key":"Alaska", "value":"Anchorage"},
    {"id":"0A2056EC-4C2E-4285-8CCE-EA0F4C71D353", "key":"Wisconsin", "value":"Milwaukee"},
    {"id":"322DC6B3-3B5E-4310-B674-6957A40A4D03", "key":"Wisconsin", "value":"Green Bay"},
    {"id":"E1371AA5-18DB-48A4-AD90-B212030E6C6F", "key":"Wisconsin", "value":"Madison"}
]}

NOTE: Realize that I have had to change key by keys (plural) and then define the list of values to choose from.

Using reduce

Lets define a reduce function for getting the states of our database.

Getting unique values in CouchDB

Using this same database, if I want to retrieve the states selecting the key of the already defined map function or even if I define a map function as:

function(doc) {
    if (doc.type==="cities") emit(null, doc.state );
}

I get the states as many times, as cities for that state I have in the database (I get states duplicated).

{
    "total_rows":285,
    "offset"    :0,
    "rows"      :[
        {"id":"0254D19B-7360-459E-A9F2-715E36AD1822", "key":null, "value":"California"},
        {"id":"02C0F725-A811-492F-BCC0-8921E04899F4", "key":null, "value":"Indiana"},
        {"id":"04A29C30-CCDC-4D73-B9D4-D8ABBBA9AB46", "key":null, "value":"Texas"},
        {"id":"05C7AD05-0CC6-4C6E-A21B-E4C8344C242A", "key":null, "value":"Colorado"},
        {"id":"07A64E55-2AB1-4AA2-81E8-3D1D54508A26", "key":null, "value":"California"},
        {"id":"07CB593A-8F8A-4100-B650-BB949775EBA4", "key":null, "value":"California"},
        {"id":"07F27430-1A5A-4F12-9116-C720AE84E246", "key":null, "value":"Utah"},
        {"id":"0884A3CD-2D54-4B4C-9492-4BCF168F04DA", "key":null, "value":"California"},
        {"id":"090E0E6C-A4EC-4E84-B071-5C771ADA3DB2", "key":null, "value":"Minnesota"},
        {"id":"094E4363-69EA-443A-964D-29F3B2F04546", "key":null, "value":"Texas"},
        {"id":"0A2056EC-4C2E-4285-8CCE-EA0F4C71D353", "key":null, "value":"Wisconsin"},
        {"id":"0C835A0A-6109-4986-904B-5C6102D86EB4", "key":null, "value":"California"},
        {"id":"0CFD3158-AD42-448B-83A8-BB13C5FF87EF", "key":null, "value":"Washington"},
        {"id":"0D3EE837-0BC1-47CE-A8FA-3FA54400549C", "key":null, "value":"Ohio"},
        {"id":"10687A90-F40B-4154-BF46-A1D976C8E800", "key":null, "value":"California"}
        ...
    ]
}

The way of getting only unique values in CouchDB is defining a reduce function as follow:

function(keys, values) {
    return true;
}

and then ask CouchDB for reducing and grouping the result of map function.

Using map/reduce in jquery.couchdb.js

Choosing to reduce the result is not much different, basically I have to define the reduce function for our view:

function(keys, values) {
    return true;
}

And invoking view in jquery.couchdb is:

db.view("post20/getCities", {
    success:function (data) {
        console.log(JSON.stringify(data));
    },
    error  :function (status) {
        console.log(status);
    },
    reduce: true,
    group: true
});

And I get:

{"rows":[
    {"key":"Alabama", "value":true},
    {"key":"Alaska", "value":true},
    {"key":"Arizona", "value":true},
    {"key":"Arkansas", "value":true},
    {"key":"California", "value":true},
    ...
]}

NOTE: As an alternative to this reduce function, I might have decided to provide a little more functionality by choosing to return as value the number of cities found for that state. If so, I can simply use a built-in function called _count and my reduce would be:

_count

Yes! just _count, as I said its a built-in function and then I don’t need to provide the body of the function, the name is enough.

I would invoke the view in the same way (with reduce and group set to true) and I get:

{
    "rows":[
        {"key":"Alabama", "value":4},
        {"key":"Alaska", "value":1},
        {"key":"Arizona", "value":10},
        {"key":"Arkansas", "value":1},
        {"key":"California", "value":69},
        ...
    ]
} 

Summarizing

Adding extra attributes to a view is adding extra pairs of keyvalue to the options (second argument) of view method. Here I’ve covered key, keys, reduce and group but you can also use others as startkey and endkey:

db.view("post20/getCities", {
    success:function (data) {
        console.log(JSON.stringify(data));
    },
    error  :function (status) {
        console.log(status);
    },
    group  :true,
    reduce :true,
    startkey: "Arizona",
    endkey: "Colorado"
});

That retrieves:

{"rows":[
    {"key":"Arizona", "value":true},
    {"key":"Arkansas", "value":true},
    {"key":"California", "value":true},
    {"key":"Colorado", "value":true}
]} 

CouchApp uploading attachments (part 2)


In my previous post I presented how to upload attachments to a document using HTML (there were few lines of JavaScript for retrieving the last revision of the document).

In this post I will shift to almost doing everything in JavaScript in order to have more control.

Uploading an attachment into CouchDB using JavaScript

Simplest case: validation

The very first step is introduce a validation for checking that we have chosen a file to upload. I want to get something like:

Error on CouchApp attachment upload
Error on CouchApp attachment upload

So I start with the following HTML:

<form id="upload" method="post" enctype="multipart/form-data">
    <label style="display:none; visibility: hidden;">
        Revision :
        <input id="revision" type="text" name="_rev"/>
    </label>
    <input id="attachment" type="file" name="_attachments"/>
    <br/>
    <input type="button" value="Submit"/>
</form>

Basically it’s a form with three input: one for the revision (that is hidden and filled from JavaScript); while the second is for the attachment (the file); the last one is just a button that I will use for invoking the validation procedure.

This is the piece of code for getting document revision.

// Get the document revision
var db = $.couch.db("hermesapp");
var id = "doc_with_attachment";
db.openDoc(id, {
    success:function (result) {
        // Update revision input field
        $("#revision").val(result._rev);
    },
    error:function (a, b, c) {
        alert("Error: " + c);
        console.log("Error on openDoc:", a, b, c);
    }
});

Now, the validation code that has to run when the button is clicked:

$("input[type='button']", "#upload").click(function (ev) {
    var empty = false;
    var form = $("#upload");
    $.each($("input[type='file'][name='_attachments']", form), function (idx, input) {
        if (input.value === "") {
            empty = true;
        }
    });
    if (empty) {
        alert("No attachment file defined!");
        return;
    }
    // Submit the form with the attachment.
    ...
})

I get a reference to the form and inside the form to any input which type is file and which name is _attachments and check that all of them are not an empty string (the loop is because we can send multiple attachments by repeating this input).

Submitting the validated form might be as simple as:

// Submit the form with the attachment
form.attr("action", "/hermesapp/" + $.couch.encodeDocId(id));
form.submit();

or if I want to use ajaxSubmit from jquery.form.js:

// Submit the form with the attachment
form.ajaxSubmit({
    url:"/hermesapp/" + $.couch.encodeDocId(id),
    success:function (response) {
        alert("saved");
        console.log("response", response);
    },
    error:function (a, b, c) {
        alert("error");
        console.log("errors", a, b, c);
    }
});

Avoiding the fact of showing the message received from the server:

CouchDB message on successful upload
CouchDB message on successful upload

and getting instead:

Message on successful attachment upload in CouchDB
Message on successful attachment upload in CouchDB

NOTE: this solution requires that you use jquery.forms.js that you can already find it in your CouchDB server (since futon uses it). In order to download it in your couchapp as we did with jquery.couch.js you should access http://localhost:5984/_utils/script/jquery.form.js (replacing localhost by the IP address of your CouchDB server and saving it with the other JavaScript files (see here for more details on setting up a CouchApp).

Stay tuned!

Next post convers Uploading attachments from JavaScript in CouchDB using PUT instead of POST: why and how. Subscribe to this blog to receive notice.

CouchApp uploading attachments (part 1)


Not sure why but jquery.couchdb.js does not include a method for uploading CouchDB attachments… But I need it, so I started googling trying to find how and found this and this.

Since I’m not just a developer but also software architect and I want clean and nice solutions (avoiding subsequent problems) I tried to understand what was proposed and how it works.

CouchDB uploading attachments: the basics

For uploading an attachment I need:

  1. Database URL (ex: /couchapp)
  2. The document id (ex: doc_with_attachment)
  3. The revision number (ex: 1-967a00dff5e02add41819138abb3284d).
  4. The file(s) being uploaded.

With this information I have to do a POST to a multipart form to an URL that I build up as follow:

var url = "/couchapp/" + $.couch.encodeDocId("doc_with_attachment")

Next, I need an HTML form:

<form id="upload" method="post" action="/couchapp/doc_with_attachment">
    <label>Revision : <input id="revision" type="text" name="_rev"/></label><br/>
    <input id="attachment" type="file" name="_attachments"/><br/>
    <br/>
    <input type="submit"/>
</form>

And _rev is retrieved in HTML load time using:

// Access the DataBase
var db = $.couch.db("couchapp");
db.openDoc("doc_with_attachment", {
    success:function (result) {
        $("#revision").val(result._rev);
    },
    error:function (a, b, c) {
        alert("Error: " + c);
        console.log("Error on openDoc:", a, b, c);
    }
});

If i select a file to upload and click on Submit button what I get is:

Trying to upload an attachment in CouchDB
Trying to upload an attachment in CouchDB

That is more or less what Chris Strom already mention on this first post.

So, lets add enctype and set it to multipart/form-data:

<form id="upload" method="post" 
      action="/couchapp/doc_with_attachment" 
      enctype="multipart/form-data">
    <label>Revision : <input id="revision" type="text" name="_rev"/></label><br/>
    <input id="attachment" type="file" name="_attachments"/><br/>
    <br/>
    <input type="submit"/>
</form>

If I run it now, I get:

CouchApp upload attachment with multipart/form-data
CouchApp upload attachment with multipart/form-data

And futon shows me that the file has been actually uploaded:

Futon showing uploaded file
Futon showing uploaded file

Of course, you can hide the revision input:

CouchDB / CouchApp uploading attachment
CouchDB / CouchApp uploading attachment

and still works!
CouchDB / CouchApp uploading attachment: result
CouchDB / CouchApp uploading attachment: result

Good! pretty simple.

Stay tuned!

Next post convers Uploading attachments from JavaScript in CouchDB. Subscribe to this blog to receive notice.

Zafu: CouchDB and KendoUI (part 3)


In the previous posts I’ve explained how to deploy Kendo UI in CouchDB (here) and the four CRUD operations using CouchDB’s Standard JavaScript API (here).
On this post I will explain how to implement KendoUI DataSource transport commands using CouchDB.

Kendo UI DataSource Transport Read

1. Define map function for the view

Create in the root of your project a views and views/getTicks folders:

mkdir views
mkdir views/getTicks

and create a file named map.js as follow:

function(doc) {
  if (doc.type && doc.type === "tick") {
    emit(doc._id, doc);
  }
}

This map function emits each document in this DataBase that has type defined and equals ‘tick’. The key for the map function is the _id of the document and the value is the document itself.

2. Define the HTML for holding the grid

I will create a minimum HTML as follows

<div id="grid"></div>

3. Create Kendo UI Grid

Lets use the following code:

var grid = $("#grid").kendoGrid({
    columns:[
        { field:"tick", title:"Tick" },
        { field:"name", title:"Company" }
    ],
    dataSource:ticksDataSource
}).data("kendoGrid");

Where I define a grid showing two columns: Tick and Company and using a ticksDataSource as Data Source.

4. Create Ticks Model for using in Kendo UI DataSource

This is the Model for holding the information.

// Ticks Model
var ticksModel = {
    id:"_id",
    fields:{
        type:{ defaultValue:"tick", editable:false },
        tick:{ editable:true},
        name:{ editable:true }
    }
};

Where id define that the id is the same that CouchDB uses, plus three additional fields:

  1. type: The type of record (here it is always tick).
    This is a trick quite commonly used in CouchDB for knowing the type of information saved on each record. This is not like other DataBase Systems where I have one separate table for each type of record.
  2. tick: The tick of the company
  3. name: The Company name.

5. Create Kendo DataSource

I create ticksDataSource as follow:

// Create Grid for displaying data
var ticksDataSource = new kendo.data.DataSource({
    transport:{
        read:function (operation) {
            // Read data and populate it
            db.view("app1/getTicks", {
                        success:function (data) {
                            if (data.rows) {
                                var res = [];
                                $.each(data.rows, function (i, val) {
                                    res.push(val.value);
                                });
                                operation.success(res);
                            }
                        }
                    }
            );
        }
    },
    schema:{
        model:ticksModel
    }
});

Where I set the schema model to ticksModel that I have defined above and I define a read callback for Kendo Data Source transport. This callback is invoked each time the system needs to populate the grid.

For reading the data, I use view method of jquery.couch.js API that executes the view that I have defined above (app1/getTicks).

On success, I will get a JSON object containing an array with the records. So, I copy them into an auxiliar variable res and the return res as result by invoking operation.success(res).

And I get something like this:

Kendo UI Grid populated using DataSource transport read callback
Kendo UI Grid populated using DataSource transport read callback

Kendo UI DataSource Transport Create

Once I have implemented the callback for filling the grid, lets add the capacity for creating a new record.

1. Add button to the toolbar for creating record

I added a toolbar array containing an element equal to “create” to kendoGrid creation and specified the editable mode as popup:

var grid = $("#grid").kendoGrid({
    toolbar: [ "create" ],
    editable: "popup",
    columns:[
        { field:"tick", title:"Tick" },
        { field:"name", title:"Company" }
    ],
    dataSource:ticksDataSource
}).data("kendoGrid");

And I got:

"Add record" button in Kendo UI Grid toolbar.
“Add new record” button in Kendo UI Grid toolbar.

And if I click on “Add new record” button I get a popup window for introducing a new record:

Popup window for adding new record
Popup window for adding new record

But I did not implemented create callback into ticksDataSource transport so even I fill the form and click on update, the record is not saved in CouchDB.

2. Implement create callback

As well as I defined a create callback, I implement a callback for saving the form in CouchDB.

create:function (operation) {
    var data = operation.data;
    delete data._id;
    db.saveDoc(data,
            {
                success:function () {
                    operation.success();
                    dataSource.read();
                },
                error:function (e) {
                    operation.error("Error " + e + " while creating document.");
                }
            }
    );
},

What I do is invoking saveDoc and if succeed then refresh the grid by invoking dataSource.read() and if it fails I inform the DataSource that it failed by finishing with an operation.error.

What I get is:

Result of adding a record
Result of adding a record

NOTE: that I delete _id before saving the document. This is important since KendoUI created this field as an empty string (“”) and if  I save a document with _id defined, CouchDB believes that this is the actual value for the _id but an empty string is not a valid identifier. Conclusion: I delete it before saving the document.

Kendo UI DataSource Transport Update

What I’m going to do is add an edit button to the toolbar and on click open a popup window with the document that is selected.

1. Add Edit button

Add a button to the toolbar for editing: change toolbar definition in grid to match:

toolbar:[ "create", "edit" ]

Getting:

Kendo UI toolbar with edit button
Kendo UI toolbar with edit button

But if you click on it it actually does nothing since KendoUI does not define a default callback for an edit button in the toolbar but in a row. That would look something like this:

KendoUI in row edit button
KendoUI in row edit button

And this time if I click on edit button I actually get:

Kendo UI grid with in-row edit button
Kendo UI grid with in-row edit button

But I don’t like this edit buttons using space on each row, so lets go back to the original one and add code for making it work.

2. Add callback to toolbar edit button

What I do is bind a click event to the button such as:

$(".k-grid-edit", "#grid").click(function () {
    alert("hello");
})

Clicking on edit button I actually get the alert with a hello message.

3. Make rows selectable.

To make a row selectable I added selectable:”row” but if in addition I want to be able to navigate using the mouse then in addition I include: navigatable:true. Now my grid definition is something like:

var grid = $("#grid").kendoGrid({
    toolbar:[ "create", "edit" ],
    editable:"popup",
    selectable:"row",
    navigatable:true,
    columns:[
        { field:"tick", title:"Tick" },
        { field:"name", title:"Company" }
    ],
    dataSource:ticksDataSource
}).data("kendoGrid");

And if I select a row it looks like:

Kendo UI grid with row selected
Kendo UI grid with row selected

4. Popup edit window for selected row

Previously I just open an alert when clicking on edit. Now, I’m going to find the selected row and open a popup with the actual content of the row.

// Edit implementation
$(".k-grid-edit").click(function (e) {
    var selected = grid.select();
    if (selected && selected.length > 0) {
        $.each(selected, function (idx, elem) {
            grid.editRow(grid.select());
        });
    }
});

And when I click on editbutton I get:

Kendo UI edit popup triggered by edit button in toolbar
Kendo UI edit popup triggered by edit button in toolbar

If I modify the company name from Apple to Apple Incand click on update I will see:

Row edited but marked as not synchronized
Row edited but marked as not synchronized

Where the company name is marked as modified but not saved in the database I can actually verify this by refreshing the page.

4. Implement transport update

I need to implement Kendo UI DataSource transport update for persisting the information in the database.

update:function (operation) {
    db.saveDoc(operation.data,
            {
                success:function () {
                    operation.success();
                    ticksDataSource.read();
                },
                error:function (e) {
                    operation.error("Error " + e + " while updating document.");
                }
            });
}

If I do now edit a record and click on update I will see that the change becomes permanente and refreshing the page will show the information updated.

Kendo UI DataSource Transport Delete

Only one last callback to implement to have a full CRUD KendoUI DataSource implemented on CouchDB.

1. Add delete button

As for edit, Kendo UI library only implements the callback for delete buttons included in a row. But I will do the same that I did for edit.

The toolbar definition is:

toolbar:[ "create", "edit", "destroy" ],

The callback for when pressing the delete button (same code that edit but invoking grid.removeRow instead of grid.editRow):

// Delete implementation

// Delete implementation
$(".k-grid-delete").click(function (e) {
    var selected = grid.select();
    if (selected && selected.length > 0) {
        $.each(selected, function (idx, elem) {
            grid.removeRow(grid.select());
        });
    }
});

And the delete implementation in Kendo UI DataSource transport is:

// Delete implementation
destroy:function (operation) {
    db.removeDoc(operation.data,
            {
                success:function () {
                    operation.success();
                    dataSource.read();
                },
                error:function (e) {
                    operation.error("Error " + e + " while deleting document.");
                }
            });
}

If I select a row and click on delete button I will get a prompt window asking for confirmation and I click ok the record is deleted.

If you liked this post please click on “like” in order to let me know that you are interested and keep writing about Zafu.

If you would like to propose some subject, you are also welcome!

And that’s it!!!

Zafu: CouchDB and KendoUI (part 2)


In my previous post I explained how to deploy KendoUI inside CouchDB using CouchApp.

This was a pretty easy thing and (of course) very little benefit since we were not actually saving / retrieving data from the database.

Step1: Using jQuery CouchDB library

jquery.couch.js is the standard API shipped with CouchDB. This is what I’m going to use for Creating, Reading, Updating and Deleting data from CouchDB.

Finding jquery.couch.js

The easiest way for finding jquery.couch.js is getting the one that is shipped inside CouchDB:

  1. Open http://127.0.0.1:5984/_utils/script/jquery.couch.js in your browser and save the file.
  2. Use curl from the command line.
curl http://127.0.0.1:5984/_utils/script/jquery.couch.js > jquery.couch.js

The very initial idea would be linking your HTML with this version (by using relative paths to it) BUT according to some forums (see this) it does not work in mobile environments. Since it is not large, I do also recommend copying it to your _attachments/js folder.

Very quick tutorial about jQuery CouchDB library

NOTE: This is not really a tutorial but some basic notions.
First of all you start thinking in terms of parallelization: I mean, you should not think about methods that you invoke and execution continues when method finishes. Most (all?) methods within CouchDB JavaScript API should be considered as something that you ask for and it will (eventually) finish and you get notified about it (upon successful -or not- completion of it).
Many of jquery.couch.js methods you provide one JSON object with two fields that are callback functions:

var callbacks = {
    success: function () { alert ("Yeah!"); },
    error: function () { alert ("Oops!"); }
}

1. Including the API

After including jQuery library include jquery.couch.js:

<!-- jQuery CouchDB scripts -->
<script src="js/jquery.min.js" type="text/javascript"></script>
<script src="js/jquery.couch.js" type="text/javascript"></script>

2. Accessing the database

Define a variable that we will use throughout the code:

// Reference to the database
var db = $.couch.db("app1");

NOTE: Remember that you might need to login before start using the database.

3. Create document

Invoke saveDoc method from db with two arguments: JSON document being saved and callbacks for success or error.

var db = $.couch.db("app1");
var data = { type:'tick', tick: 'AAPL', name: 'Apple' };
db.saveDoc (data, {
    success: function (d) { alert ("Yeah!: " + d._id); },
    error: function () { alert ("Oops!"); }
});

IMPORTANT:It is very important to note that data should either not include _id field or define it with a value that does not exist. A value that already exists represents a collision and hence an error. An empty string is not valid either.
success receives as argument an object with the identifier (id) and revision (rev) of the created document.

4. Reading a document

Invoke openDoc with document identifier as first argument and callback functions as second.

db.openDoc("63806bde88c403b5c5aadceba60260e9", {
    success: function (d) { alert ("Yeah!" + d.tick + "->" + d.name); },
    error: function () { alert ("Oops!"); }
});

On success you get the document.

5. Updating a document

Invoke saveDoc with the document update (it must include the identifier _id and revision _rev) and callback functions.

var data = { _id:'63806bde88c403b5c5aadceba60260e9', _rev:'1-f10e140d3debd4cd3c524737c2d0e8a6',
    type:'tick', tick: 'AAPL', name: 'Apple Inc.' };
db.saveDoc(data, {
    success: function (d) { alert ("Yeah!" + d.rev); },
    error: function () { alert ("Oops!"); }
});

6. Delete a document

Invoke removeDoc with one JSON object including the document identifier _id and revision _rev and a second argument for the callbacks.

var data = { _id:'63806bde88c403b5c5aadceba60274ef', _rev:'1-c8af95a9d3c4d9ea3cd720f25415ffe9' };
db.removeDoc(data, {
    success: function (d) { alert ("Yeah! " + d.ok); },
    error: function () { alert ("Oops!"); }
});

7. Views

Invoke view with the name of the view that you want to execute. On return you get a JSON structure with a field rows containing a vector with the information retrieved.

db.view("app1/getTicks", {
    success: function (d) { alert ("Yeah! Retrieved: " + d.ok + " documents"); },
    error: function () { alert ("Oops!"); }
});

And that’s about it. For a more complete description of these interfaces, click here!.
Next post (here) is start using it for populating a Kendo UI grid.