Skip to content
pol edited this page Sep 12, 2010 · 4 revisions

Views in CouchDB

Most of the information here is just a collation of various readings done (including the CouchDB Wiki and certain articles such as this CouchDB Javascript tutorial)

Introduction

Views are used to query CouchDB. Think of it as a Lucene/Ferret index with filtering capabilities for all JSON documents stored in a CouchDB database. Views have certain intelligence, which means that if documents within the database are updated, the changes will be reflected in the view automatically. There are two types of views:

  • Permanent: They are stored inside a CouchDB database as special documents called design documents (they are still regular CouchDB documents, i.e. JSON docs)

Execution method: HTTP GET to URI {db_name}/view/{viewname}. So if your database is called blogs and your view is called get_all, then the URL is blogs/_view/getall

  • Temporary: Temporary views are more expensive that permanent views and are executed on the fly. They are not stored inside the CouchDB database.

Execution method: HTTP Post to URI {db_name}/_temp_view. Body of HTTP Post is the Javascript function which queries the DB, and the Content-Type header is set to text/javascript.

Anatomy of a View

All view functions will have this same basic structure as in Code Listing 1.

  • The doc parameter represents a CouchDB document which satisfies the condition specified by a view.
  • The first parameter for the method map represents the key. A key gives the user the option to pass a parameter to a view.
  • The second parameter (doc) for the method map represents what needs to be returned in the result set. If doc is passed, only the document ID and the revision ID are passed back in the result set. But this can be extended to contain any number of document attributes. (See Example 3)

Source Code Examples

Example 1

In Code Listing 1, since the key here is null, the view given in Code Listing 1 puts all documents in the database in the view.

Code Listing 1


function(doc) { map(null, doc); }

Example 2

But for example, in Code Listing 2 (source: CM Lenz’ tutorial on CouchDB Joins), we see a document which represents a blog which has many comments (assume the name of the database is blogs). The view defined in Code Listing 3 (assume the name of the view is comments_by_author) gives a view which adds all comments for a blog to the view. Note that the key used is the ‘author’ field in the blog document. Thus to get all comments for the author ‘john’, the following URL needs to be used for an HTTP GET request /blogs/view/comments_byauthor?key=john

Code Listing 2


{ "_id": "myslug", "_rev": "123456", "author": "john", "title": "My blog post", "content": "Bla bla bla …", "comments": [ {"author": "jack", "content": "…"}, {"author": "jane", "content": "…"} ] } </pre>

Code Listing 3


function(doc) { for (var i in doc.comments) { map(doc.comments[i].author, doc.comments[i].content); } }

Example 3

In another example, to (hopefully) drive home the point, a view used to gather the titles of all blogs who’s title’s length is greater than 100, using the ‘author’ as the key, will be as given in Code Listing 4 (Assume the name of the view is long_titles). Thus to get all blogs written by ‘john’ who’s title-length is greater than 100 characters, an HTTP GET request need to be sent to the URL: /blogs/view/longtitles?key=john

To get all blogs who’s title-length is greater than 100 (and not just those written by john), an HTTP GET request needs to be sent to the URL: /blogs/view/longtitles

Code Listing 4


function(doc) { if(doc.title.length > 100) { map(doc.author, doc.title); } }

Please note that keys can be arbitrary JSON structures (as explained here and not just strings, thus allowing more complex queries, but the explanation of that will be left to a later point in time.