Being able to map documents to (key, value) pairs is really useful, but the views installed in my previous post return all pairs that the view calculates in no specific order. What if I want only the titles of articles posted in December 2007?

In the last article I mentioned in passing that it was possible to emit keys as part of the map method of a view. Keys are used to order and filter a result set. Details about how keys are sorted against each other can be found in the CouchDB view collation specification. To order and filter documents by date posted I just need to emit doc.posted_at as the key when I'm writing my map method.

// Get all article titles ordered by posted date.
function(doc) {
  if(doc.type == 'article') {
    emit([doc.posted_at], doc.title);
  }
}

It's worth noting that I've chosen always to have my keys be arrays. This is a personal preference - it was easier to make my branch of ActiveCouch support multiple keys if I assumed this.

A typical result set from running this map might look like the following.


// GET /blog/_articles/titles_by_posted_at
{
"total_rows":75,
"offset":0,
"rows":[
  {"id":"showing-multiple-message-types-with-the-flash","key":["2007-12-15T20:14:02Z"],"value":"Showing multiple message types with the flash"},
  {"id":"class-instance-and-singleton-methods","key":["2007-12-20T14:50:41Z"],"value":"Class, Instance and Singleton methods"},
  // ... and so on ...
}

Now that the articles are keyed by date note that they're ordered by the data - the lower the date value the earlier they are in the results.

The key can also be used to pick out specific articles. Maybe I want just the article that was published at 2007-12-20T14:50:41Z, I just ask for that key from the results.

// GET /blog/_articles/titles_by_posted_at?key=["2007-12-20T14:50:41Z"]

{"total_rows":75,"offset":0,"rows":[
{"id":"class-instance-and-singleton-methods","key":["2007-12-20T20:50:41Z"],"value":"Class, Instance and Singleton methods"}
]}

If I wanted to pull out a range of results I can specify a startkey and an endkey and all results that have a key that falls between the two will be returned. I can take advantage of the fact that the keys are strings too, and specify times that might otherwise not make sense such as 24:00 to make sure that I get all articles that I'm interested in.

// GET /blog/_view/articles/titles_by_created_at?startkey=[%222007-12-01T00:00:00Z%22]&endkey=[%222007-12-31T24:00:00Z%22]

{"total_rows":75,"offset":0,"rows":[
{"id":"showing-multiple-message-types-with-the-flash","key":["2007-12-15T20:14:02Z"],"value":"Showing multiple message types with the flash"},
{"id":"class-instance-and-singleton-methods","key":["2007-12-20T14:50:41Z"],"value":"Class, Instance and Singleton methods"}
]}

The key, startkey and endkey are three of a whole bunch of parameters available as part of CouchDB's view API. More information can be found at http://wiki.apache.org/couchdb/HTTP_view_API.

written by
Craig
published
2009-01-22
Disagree? Found a typo? Got a question?
If you'd like to have a conversation about this post, email craig@barkingiguana.com. I don't bite.
You can verify that I've written this post by following the verification instructions:
curl -LO http://barkingiguana.com/2009/01/22/filtering-and-ordering-couchdb-view-results.html.orig
curl -LO http://barkingiguana.com/2009/01/22/filtering-and-ordering-couchdb-view-results.html.orig.asc
gpg --verify filtering-and-ordering-couchdb-view-results.html.orig{.asc,}