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.

HTTP View API

See also the official documentation for this topic.

An introduction to the CouchDB HTTP view API.

Basics

Views are the primary tool used for querying and reporting on CouchDB databases. They are defined in JavaScript (although there are other query servers available). For a more detailed introduction to views see Introduction_to_CouchDB_views.

Creating Views

To create a permanent view, the functions must first be saved into special design documents (well, they are not really special, we just call them special but in reality, they are regular documents, just with a special ID). The IDs of design documents must begin with _design/ and have a special views attribute that have a map member and an optional reduce member to hold the view functions. All the views in one design document are indexed whenever any of them gets queried.

A design document that defines all, by_lastname, and total_purchases views might look like this:

   1 {
   2   "_id":"_design/company",
   3   "_rev":"12345",
   4   "language": "javascript",
   5   "views":
   6   {
   7     "all": {
   8       "map": "function(doc) { if (doc.Type == 'customer')  emit(null, doc) }"
   9     },
  10     "by_lastname": {
  11       "map": "function(doc) { if (doc.Type == 'customer')  emit(doc.LastName, doc) }"
  12     },
  13     "total_purchases": {
  14       "map": "function(doc) { if (doc.Type == 'purchase')  emit(doc.Customer, doc.Amount) }",
  15       "reduce": "function(keys, values) { return sum(values) }"
  16     }
  17   }
  18 }

The language property of the design document tells CouchDB the language of the functions inside it -- map, reduce, validate, show, list, etc. Based on this it selects the appropriate ViewServer (as specified in your couch.ini file). The default is to assume Javascript, so this property can be omitted for Javascript-based design documents.

Altering/Changing Views

To change a view or multiple view just alter the design document (see HttpDocumentApi) they are stored in and save it as a new revision. This causes all the views in that design document to be rebuilt on the next access in case the view code has been changed.

Access/Query

Once this document is saved into a database, then the all view can be retrieved at the URL:

Example:

GET /some_database/_design/company/_view/all HTTP/1.0
Date: Thu, 17 Aug 2006 05:39:28 +0000GMT

And will result in the following response:

 HTTP/1.1 200 OK
 Date: Thu, 17 Aug 2006 05:39:28 +0000GMT
 Content-Length: 318
 Connection: close

 {
    "total_rows": 3,
    "offset": 0,
    "rows": [{
        "id":"64ACF01B05F53ACFEC48C062A5D01D89",
        "key": null,
        "value": {
          "LastName":"Katz",
          "FirstName":"Damien",
          "Address":"2407 Sawyer drive, Charlotte NC",
          "Phone":012555754211
        }
      }, {
        "id":"5D01D8964ACF01B05F53ACFEC48C062A",
        "key": null,
        "value": {
          "LastName":"Kerr",
          "FirstName":"Wayne",
          "Address":"123 Fake st., such and such",
          "Phone":88721320939
        }
      }, {
        "id":"EC48C062A5D01D8964ACF01B05F53ACF",
        "key": null,
        "value":
        {
          "LastName":"McCracken",
          "FirstName":"Phil",
          "Address":"1234 Fake st., such and such",
          "Phone":7766552342
        }
      }
    ]
 }

View Generation Options

There are two view indexing options that can be defined in a design document as boolean properties of an 'options' sub-object. (Unlike the querying options below, these aren't URL parameters because they take effect when the view index is generated, not when it's accessed.)

   1     "options" : {
   2         "local_seq" : true,
   3         "include_design" : true
   4     }

local_seq makes documents' local sequence numbers available to map functions (as a '_local_seq' document property).

include_design causes map functions to be called on design documents as well as regular documents.

Querying Options

Columns can be a list of values, there is no set limit to the number of values or amount of data that columns can hold.

The following URL query arguments for GET/HEAD requests are allowed:

Parameter

Value

Default value

Description

key

key-value

-

Must be a proper URL encoded JSON value

keys

array of key-values

-

Must be a proper URL encoded JSON array value

startkey

key-value

-

Must be a proper URL encoded JSON value

startkey_docid

document id

-

document id to start with (to allow pagination for duplicate startkeys)

endkey

key-value

-

Must be a proper URL encoded JSON value

endkey_docid

document id

-

last document id to include in the output (to allow pagination for duplicate endkeys)

limit

number of docs

-

Limit the number of documents in the output

stale

ok / update_after

-

If stale=ok is set, CouchDB will not refresh the view even if it is stale, the benefit is a an improved query latency. If stale=update_after is set, CouchDB will update the view after the stale result is returned. update_after was added in version 1.1.0.

descending

true / false

false

change the direction of search

skip

number of docs

0

skip n number of documents

group

true

false

The group option controls whether the reduce function reduces to a set of distinct keys or to a single result row.

group_level

number

-

see below

reduce

true / false

true

use the reduce function of the view. It defaults to true, if a reduce function is defined and to false otherwise.

include_docs

true / false

false

automatically fetch and include the document which emitted each view entry

inclusive_end

true / false

true

Controls whether the endkey is included in the result. It defaults to true.

update_seq

true / false

false

Response includes an update_seq value indicating which sequence id of the database the view reflects

Since 0.9 you can also issue POST requests to views where you can send the following JSON structure in the body:

{"keys": ["key1", "key2", ...]}

A JSON structure of {"keys": ["key1", "key2", ...]} can be posted to any user defined view or _all_docs to retrieve just the view rows matching that set of keys. Rows are returned in the order of the keys specified. Combining this feature with include_docs=true results in the so-called multi-document-fetch feature.

The same response can be obtained using the keys parameter, but you need to URL encode the value. For example you can get two documents with _ids ID1 and ID2 from database DB with:

curl -v 'http://localhost:5984/DB/_all_docs?keys=%5B%22ID1%22,%22ID2%22%5D&include_docs=true'

key, keys, startkey, and endkey need to be properly JSON encoded values. For example, startkey="string" for a string value or startkey=["foo", 1, {}]. Be aware that you have to do proper URL encoding on complex values.

If you specify ?limit=0 you don't get any data, but all meta-data for this View. The number of documents in this View for example.

Note: Multiple keys request to a reduce function only supports group=true and NO group_level (identical to group_level=exact). The resulting error is "Multi-key fetchs for reduce view must include group=true"

The skip option should only be used with small values, as skipping a large range of documents this way is inefficient (it scans the index from the startkey and then skips N elements, but still needs to read all the index values to do that). For efficient paging you'll need to use startkey and limit. If you expect to have multiple documents emit identical keys, you'll need to use startkey_docid in addition to startkey to paginate correctly. The reason is that startkey alone will no longer be sufficient to uniquely identify a row.

The stale option can be used for higher performance at the cost of possibly not seeing the all latest data. If you set the stale option to ok, CouchDB may not perform any refreshing on the view that may be necessary. Using this option essentially tells CouchDB that if a reference to the view index is available in memory (ie, if the view has been queried at least once since couch was started), go ahead and use it, even if it may be out of date. The result is that for a highly trafficked view, end users can see lower latency, although they may not get the latest data. However, if there is no view index pointer in memory, the behavior with this option is that same as the behavior without the option. If your application use stale=ok for end-user queries, you'll need either a cron or a notification process like the one described in Regenerating_views_on_update, which queries without stale=ok to ensure that the view is kept reasonably up to date.

View rows are sorted by the key; specifying descending=true will reverse their order. Note that the descending option is applied before any key filtering, so you may need to swap the values of the startkey and endkey options to get the expected results. The sorting itself is described in ViewCollation.

The group and group_level options control whether the reduce function reduces to a set of distinct keys or to a single result row. group_level lets you specify how many items of the key array are used in grouping; group=true is effectively the same as group_level=999 (for an arbitrarily high value of 999.) Don't specify both group and group_level; the second one given will override the first.

If a view contains both a map and reduce function, querying that view will by default return the result of the reduce function. The result of the map function only may be retrieved by passing reduce=false as a query parameter.

The include_docs option will include the associated document. However, the user should keep in mind that there is a race condition when using this option. It is possible that between reading the view data and fetching the corresponding document that the document has changed. If you want to alleviate such concerns you should emit an object with a _rev attribute as in emit(key, {"_rev": doc._rev}). This alleviates the race condition but leaves the possibility that the returned document has been deleted (in which case, it includes the "_deleted": true attribute). Note: include_docs will cause a single document lookup per returned view result row. This adds significant strain on the storage system if you are under high load or return a lot of rows per request. If you are concerned about this, you can emit the full doc in each row; this will increase view index time and space requirements, but will make view reads optimally fast.

The inclusive_end option controls whether the endkey is included in the result. It defaults to true.

In a reduced view result, you need to use startkey and endkey to match rows instead of the key parameter.

Note: If you use group or group_level, total_rows and offset will be omitted from the results (for performance reasons, to avoid scanning the entire tree.)

Getting Information about Design Documents (and their Views)

You can query the design document (_design/test in this case) by GET for some information on the view:

curl -X GET http://localhost:5984/databasename/_design/test/_info

will produce something like this:

   1 {
   2     "name": "test",
   3     "view_index": {
   4         "compact_running": false,
   5         "disk_size": 4188,
   6         "language": "javascript",
   7         "purge_seq": 0,
   8         "signature": "07ca32cf9b0de9c915c5d9ce653cdca3",
   9         "update_seq": 4,
  10         "updater_running": false,
  11         "waiting_clients": 0,
  12         "waiting_commit": false
  13     }
  14 }

Meaning of the status hash

Key

Description

name

Name of the design document without the _design prefix (string)

view_index

Contains information on the views (JSON object)

Subkeys of view_index

Description

signature

The MD5 representation of the views of a design document (string)

language

Language of the views used (string)

disk_size

Size in Bytes of the views on disk (int)

updater_running

Indicates if an update process is running (boolean)

compact_running

Indicates if view compaction is running (boolean)

waiting_commit

Indicates if this view is ahead of db commits or not (boolean)

waiting_clients

How many clients are waiting on views of this design document (int)

update_seq

The update sequence of the corresponding database that has been indexed (int)

purge_seq

The purge sequence that has been processed (int)

Debugging Views

When creating views, CouchDB will check the syntax of the submitted JSON, but the view functions themselves will not be syntax checked by the Javascript interpreter. And if any one of the view functions has a syntax error, none of the view functions in that design document will execute. Perhaps test your functions in a temporary view before saving them in the database.

As of r660140 there is a log function available in the views, which logs to the couch.log. It can be helpful for debugging but hinders performance, so it should be used sparingly in production systems.

   1 {
   2   "map": "function(doc) { log(doc); }"
   3 }

Playing with (malformed) views is currently the best way to bring the couchdb server in an unstable state. Also the Futon Web-Client does not interact very well with errors in views. Some suggestions for view development:

Sharing Code Between Views

There are no development plans to share code/functions between views. Each view function is stored according to a hash of their byte representation, so it is important that a function does not load any additional code, changing its behavior without changing its byte-string. Hence the use-case for CouchApp. In CouchApp, it is possible to include directives within any Javascript functions that directs CouchApp to modify the functions before they are uploaded to the CouchDb server.

An explanation of CouchApp directives is found in Chris Strom's blog. Using CouchApp, one can insert Javascript code from a different file into a view map function using the "code" CouchApp directive. For example:

   1 {
   2   "map": "function(doc) {
   3     // Next line is CouchApp directive
   4     // !code dir/file.js
   5 
   6     // isADocOfInterest is defined in dir/file.js
   7     if( isADocOfInterest(doc) ) {
   8       emit(doc.key, doc);
   9     }
  10   }"
  11 }

Since CouchDB 0.11 it is possible to share code in show, list, update, and validation functions. See CommonJS_Modules for details.

See also Javascript Pattern to Share Code Between View and Other Functions

View Cleanup

Old view output remains on disk until you explicitly run cleanup. To run cleanup for a particular database;

POST /some_database/_view_cleanup

View Compaction

If you have very large views or are tight on space, you might consider Compaction as well. To run compact for a particular view on a particular database;

POST /some_database/_compact/designname

In my case, views that were 26G, 27G, 39G, and 40G, shrank to 2.8G, 2.8G, 3.4G, and 3.5G, respectively.

Temporary Views

One-off queries (eg. views you don't want to save in the CouchDB database) can be done via the special view _temp_view. Temporary views are only good during development. Final code should not rely on them as they are very expensive to compute each time they get called and they get increasingly slower the more data you have in a database. If you think you can't solve something in a permanent view that you can solve in an ad-hoc view, you might want to reconsider. (TODO: add typical examples and solutions).

POST /some_database/_temp_view  HTTP/1.0
Content-Length: 48
Date: Mon, 10 Sep 2007 17:11:10 +0200
Content-Type: application/json

{
  "map" : "function(doc) { if (doc.foo=='bar') { emit(null, doc.foo); } }"
}

Could result in the following response:

   1 {
   2   "total_rows": 1,
   3   "offset": 0,
   4   "rows": [{
   5       "id": "AE1AD84316B903AD46EF396CAFE8E50F",
   6       "key": null,
   7       "value": "bar"
   8     }
   9   ]
  10 }

NOTE: couchdb 0.9.0 requires Content-Type: application/json on POSTs to _temp_view

HTTP_view_API (last edited 2013-06-05 21:40:50 by NathanVanderWilt)