We have a new wiki. The migration is not 100% complete. You can help out by moving pages across. This wiki will exist for as long as there are pages left.

The official documentation has moved to http://docs.couchdb.org — The transition is not 100% complete, but http://docs.couchdb.org should be seen as having the latest info. In some cases, the wiki still has some more or older info on certain topics inside CouchDB.

You need to be added to the ContributorsGroup to edit the wiki. But don't worry! Just email any Mailing List or grab us on IRC and let us know your user name.

View Snippets

This page collects code snippets to be used in your Views. They are mainly meant to help get your head around the map/reduce approach to accessing database content.

Remember: the Futon web client silently adds group=true to your views.

Common mistakes

When creating a reduce function, a re-reduce should behave in the same way as the regular reduce. The reason is that CouchDB doesn't necessarily call re-reduce on your map results.

Think about it this way: If you have a bunch of values V1 V2 V3 for key K, then you can get the combined result either by calling reduce([K,K,K],[V1,V2,V3],0) or by re-reducing the individual results: reduce(null,[R1,R2,R3],1). This depends on what your view results look like internally.

Get docs with a particular user id

   1 // map
   2 function(doc) {
   3   if (doc.user_id) {
   4     emit(doc.user_id, null);
   5   }
   6 }

Then query with key=USER_ID to get all the rows that match that user.

Get all documents which have an attachment

This lists only the documents which have an attachment.

   1 // map
   2 function(doc) {
   3   if (doc._attachments) {
   4     emit(doc._id, null);
   5   }
   6 }

In SQL this would be something like SELECT id FROM table WHERE attachment IS NOT NULL.

Count documents with and without an attachment

Call this with group=true or you only get the combined number of documents with and without attachments.

   1 // map
   2 function(doc) {
   3   if (doc._attachments) {
   4     emit("with attachment", 1);
   5   }
   6   else {
   7     emit("without attachment", 1);
   8   }
   9 }

   1 // reduce
   2 function(keys, values) {
   3    return sum(values);
   4 }

Using curl you can call it like this:

curl -s -i -X POST -H 'Content-Type: application/json'
  -d '{"map": "function(doc){if(doc._attachments) {emit(\"with\",1);} else {emit(\"without\",1);}}",
  "reduce": "function(keys, values) {return sum(values);}"}'
  'http://localhost:5984/somedb/_temp_view?group=true'

In SQL this would be something along the lines of SELECT num_attachments FROM table GROUP BY num_attachments (but this would give extra output for rows containing more than one attachment).

Generating a list of unique values

Here we use the fact that the key for a view result can be an array. Suppose you have a map that generates (key, value) pairs with many duplicates and you want to remove the duplicates. To do so, use emit([key, value], null) as the map output.

Call this with group=true or you only get null.

   1 // map
   2 function(doc) {
   3   for (var i in doc.links)
   4     emit([doc.parent, i], null);
   5   }
   6 }

   1 // reduce
   2 function(keys, values) {
   3    return null;
   4 }

This will give you results like

   1 {"rows":[
   2 {"key":["thisparent","thatlink"],"value":null},
   3 {"key":["thisparent","thatotherlink"],"value":null}
   4 ]}

You can then get all the rows for the key "thisparent" with the view parameters startkey=["thisparent"]&endkey=["thisparent",{}]&inclusive_end=false

Note that the trick here is using the key for what you want to make unique. You can combine this with the counting above to get a count of duplicate values:

   1 // map
   2 function(doc) {
   3   for (var i in doc.links)
   4     emit([doc.parent, i], 1);
   5   }
   6 }

   1 // reduce
   2 function(keys, values) {
   3    return sum(values);
   4 }

If you then want to know the total count for each parent, you can use the group_level view parameter: startkey=["thisparent"]&endkey=["thisparent",{}]&inclusive_end=false&group_level=1

Get contents of an object with specific attributes e.g. doc.objects.[0].attribute

   1 // map
   2 function(doc) {
   3   for (var idx in doc.objects) {
   4     emit(doc.objects[idx], attribute)
   5   }
   6 }

Arbitrarily query against any document property ("uniview")

Note: This is not a generally recommended approach, as your view size will be (# of documents * # of document fields). However, if application's query behaviour cannot be determined ahead of time, disk space is essentially free, and you do not wish to add views later, this may be your only option.

   1 // map
   2 function(doc) {
   3   for (prop in doc) {
   4     emit([prop, doc[prop]], null);
   5   }
   6 }

Query a specific property by using startkey=["property", 0]&endkey=["property", {}] .

As an example, for a database of person data, startkey=["age", 18]&endkey=["age", {}]&include_docs=true to retrieve all legal adults

View_Snippets (last edited 2012-01-24 19:49:30 by JoanTouzet)