couchdb-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From d..@apache.org
Subject git commit: Docs: _changes feed
Date Tue, 02 Oct 2012 20:42:09 GMT
Updated Branches:
  refs/heads/docs d4cdb2b34 -> 03fde1dae


Docs: _changes feed


Project: http://git-wip-us.apache.org/repos/asf/couchdb/repo
Commit: http://git-wip-us.apache.org/repos/asf/couchdb/commit/03fde1da
Tree: http://git-wip-us.apache.org/repos/asf/couchdb/tree/03fde1da
Diff: http://git-wip-us.apache.org/repos/asf/couchdb/diff/03fde1da

Branch: refs/heads/docs
Commit: 03fde1daed5a31f05e83b0d1723a07375c9ff311
Parents: d4cdb2b
Author: Alexander Shorin <kxepal@gmail.com>
Authored: Tue Oct 2 22:37:42 2012 +0200
Committer: Dave Cottlehuber <dch@apache.org>
Committed: Tue Oct 2 22:37:42 2012 +0200

----------------------------------------------------------------------
 share/doc/src/changes.rst        |  274 +++++++++++++++++++++++++++++++-
 share/doc/src/json-structure.rst |  193 +++++++++++++++++++++++
 2 files changed, 458 insertions(+), 9 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/couchdb/blob/03fde1da/share/doc/src/changes.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/changes.rst b/share/doc/src/changes.rst
index bd50860..f0d61ed 100644
--- a/share/doc/src/changes.rst
+++ b/share/doc/src/changes.rst
@@ -16,28 +16,284 @@
 Changes Feed
 ============
 
-The ``_changes`` feed can now be used to watch changes to specific
-document ID's or the list of ``_design`` documents in a database. If the
-``filters`` parameter is set to ``_doc_ids`` a list of doc IDs can be
-passed in the "doc_ids" as a JSON array.
- 
-
 Polling
 =======
 
- 
+A list of changes made to documents in the database, in the order they were
+made, can be obtained from the database's ``_changes`` resource. You can query
+the ``_changes`` resource by issuing a ``GET`` request with the following
+(optional) parameters:
+
++--------------+--------------------------------+---------------+--------------+
+| Parameter    | Value                          | Default Value |  Notes       |
++==============+================================+===============+==============+
+| since        | seqnum / now                   | 0             | \(1)         |
++--------------+--------------------------------+---------------+--------------+
+| limit        | maxsequences                   | none          | \(2)         |
++--------------+--------------------------------+---------------+--------------+
+| descending   | boolean                        | false         | \(3)         |
++--------------+--------------------------------+---------------+--------------+
+| feed         | normal / longpoll / continuous | normal        | \(4)         |
++--------------+--------------------------------+---------------+--------------+
+| heartbeat    | milliseconds                   | 60000         | \(5)         |
++--------------+--------------------------------+---------------+--------------+
+| timeout      | milliseconds                   | 60000         | \(6)         |
++--------------+--------------------------------+---------------+--------------+
+| filter       | designdoc/filtername / _view   | none          | \(7)         |
++--------------+--------------------------------+---------------+--------------+
+| include_docs | boolean                        | false         | \(8)         |
++--------------+--------------------------------+---------------+--------------+
+| style        | all_docs / main_only           | main_only     | \(9)         |
++--------------+--------------------------------+---------------+--------------+
+| view         | designdoc/filtername           | none          | \(10)        |
++--------------+--------------------------------+---------------+--------------+
+
+Notes:
+
+(1) Start the results from the change immediately after the given sequence
+    number.
+
+(2) Limit number of result rows to the specified value (note that using 0 here
+    has the same effect as 1).
+
+(3) Return the change results in descending sequence order (most recent change
+    first)
+
+(4) Select the type of feed.
+
+(5) Period in milliseconds after which an empty line is sent in the results.
+    Only applicable for `longpoll` or `continuous` feeds. Overrides any timeout
+    to keep the feed alive indefinitely.
+
+(6) Maximum period in milliseconds to wait for a change before the response is
+    sent, even if there are no results. Only applicable for `longpoll` or
+    `continuous` feeds. Note that 60000 is also the default maximum timeout to
+    prevent undetected dead connections.
+
+    You can change the default maximum timeout in your ini-configuration:
+
+    .. code-block:: ini
+
+        [httpd]
+        changes_timeout=#millisecs
+
+(7) Reference a filter function from a design document to selectively get
+    updates. See the `section in the book`_ for more information.
+
+(8) Include the associated document with each result. If there are conflicts,
+    only the winning revision is returned.
+
+(9) Specifies how many revisions are returned in the changes array.
+    The default, `main_only`, will only return the current "winning" revision;
+    `all_docs` will return all leaf revisions (including conflicts and deleted
+    former conflicts.)
+
+(10) Allows to use view functions as filters. It requires to set ``filter``
+     special value `_view` to enable this feature. Documents counted as "passed"
+     for view filter in case if map function emits at least one record for them.
+
+.. versionchanged:: 0.11.0 added ``include_docs`` parameter
+.. versionchanged:: 1.2.0 added ``view`` parameter and special value `_view`
+   for ``filter`` one
+.. versionchanged:: 1.3.0 ``since`` parameter could take `now` value to start
+   listen changes since current seq number.
+
+By default all changes are immediately returned as a JSON object::
+
+    GET /somedatabase/_changes HTTP/1.1
+
+.. code-block:: javascript
+
+    {"results":[
+    {"seq":1,"id":"fresh","changes":[{"rev":"1-967a00dff5e02add41819138abb3284d"}]},
+    {"seq":3,"id":"updated","changes":[{"rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}]},
+    {"seq":5,"id":"deleted","changes":[{"rev":"2-eec205a9d413992850a6e32678485900"}],"deleted":true}
+    ],
+    "last_seq":5}
+
+``results`` is the list of changes in sequential order. New and changed
+documents only differ in the value of the rev; deleted documents include the
+``"deleted": true`` attribute. (In the ``style=all_docs mode``, deleted applies
+only to the current/winning revision. The other revisions listed might be
+deleted even if there is no deleted property; you have to ``GET`` them
+individually to make sure.)
+
+``last_seq`` is the sequence number of the last update returned. (Currently it
+will always be the same as the seq of the last item in results.)
+
+Sending a ``since`` param in the query string skips all changes up to and
+including the given sequence number::
+
+    GET /somedatabase/_changes?since=3 HTTP/1.1
+
+.. code-block:: javascript
+
+    {"results":[
+    {"seq":5,"id":"deleted","changes":[{"rev":"2-eec205a9d413992850a6e32678485900"}],"deleted":true}
+    ],
+    "last_seq":5} 
 
 Long Polling
 ============
 
- 
+The `longpoll` feed (probably most useful used from a browser) is a more
+efficient form of polling that waits for a change to occur before the response
+is sent. `longpoll` avoids the need to frequently poll CouchDB to discover
+nothing has changed!
+
+The response is basically the same JSON as is sent for the normal feed.
+
+A timeout limits the maximum length of time the connection is open. If there
+are no changes before the timeout expires the response's results will be an
+empty list.  
 
 Continuous
 ==========
 
- 
+Polling the CouchDB server is not a good thing to do. Setting up new HTTP
+connections just to tell the client that nothing happened puts unnecessary
+strain on CouchDB.
+
+A continuous feed stays open and connected to the database until explicitly
+closed and changes are sent to the client as they happen, i.e. in near
+real-time.
+
+The continuous feed's response is a little different than the other feed types
+to simplify the job of the client - each line of the response is either empty
+or a JSON object representing a single change, as found in the normal feed's
+results.
+
+.. code-block:: text
+
+    GET /somedatabase/_changes?feed=continuous HTTP/1.1
+
+.. code-block:: javascript
+
+    {"seq":1,"id":"fresh","changes":[{"rev":"1-967a00dff5e02add41819138abb3284d"}]}
+    {"seq":3,"id":"updated","changes":[{"rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}]}
+    {"seq":5,"id":"deleted","changes":[{"rev":"2-eec205a9d413992850a6e32678485900"}],"deleted":true}
+    ... tum tee tum ...
+    {"seq":6,"id":"updated","changes":[{"rev":"3-825cb35de44c433bfb2df415563a19de"}]}
+
+Obviously, `... tum tee tum ...` does not appear in the actual response, but
+represents a long pause before the change with seq 6 occurred.  
 
 Filters
 =======
 
+Classic filters
+---------------
+
+By default changes feed emits all database documents changes. But if you're
+waiting for some special changes it's not optimal to process each record.
+
+Filters are special design document functions that allows changes feed to emit
+only specific documents that passed filter rules.
+
+Let assume that our database is mailbox and we need to listen changes to handle
+only new mails (documents with status `new`). Assuming that, our filter function
+would looks like next one:
+
+.. code-block:: javascript
+
+  function(doc, req){
+    // we need only `mail` documents
+    if (doc.type != 'mail'){
+      return false;
+    }
+    // we're interested only in `new` ones
+    if (doc.status != 'new'){
+      return false;
+    }
+    return true; // passed!
+  }
  
+Filter function must return true in fact if document passed all defined rules.
+Now, if you apply this function to changes feed, you're changes feed will emit
+only changes about "new mail"::
+
+
+    GET /somedatabase/_changes?filter=mailbox/new_mail HTTP/1.1
+
+.. code-block:: javascript
+
+    {"results":[
+    {"seq":1,"id":"df8eca9da37dade42ee4d7aa3401f1dd","changes":[{"rev":"1-c2e0085a21d34fa1cecb6dc26a4ae657"}]},
+    {"seq":7,"id":"df8eca9da37dade42ee4d7aa34024714","changes":[{"rev":"1-29d748a6e87b43db967fe338bcb08d74"}]},
+    ],
+    "last_seq":27}
+
+Note, that ``last_seq`` number is 27, but we'd received only two records.
+Seems like any other changes was about documents, that hadn't passed our filter.
+
+Probably, we also need to filter changes feed of our mailbox not only by single
+status value: we also interested in statuses like "spam" to update spam-filter
+heuristic rules, "outgoing" to let mail daemon actually send mails and so on.
+Creating a lot of similar functions that actually does same work isn't good
+idea - so we need dynamic filter to go.
+
+If you have noted, filter functions takes second argument as
+:ref:`request <request_object>` object - it allows to create dynamic filters
+based on query parameters, :ref:`user context <userctx_object>` and more.
+
+The dynamic version of our filter now will be next:
+
+.. code-block:: javascript
+
+  function(doc, req){
+    // we need only `mail` documents
+    if (doc.type != 'mail'){
+      return false;
+    }
+    // we're interested only in requested status
+    if (doc.status != req.query.status){
+      return false;
+    }
+    return true; // passed!
+  }
+
+and now we have pass `status` query parameter in request to let filter match
+only required documents::
+
+    GET /somedatabase/_changes?filter=mailbox/by_status&status=new HTTP/1.1
+
+.. code-block:: javascript
+
+    {"results":[
+    {"seq":1,"id":"df8eca9da37dade42ee4d7aa3401f1dd","changes":[{"rev":"1-c2e0085a21d34fa1cecb6dc26a4ae657"}]},
+    {"seq":7,"id":"df8eca9da37dade42ee4d7aa34024714","changes":[{"rev":"1-29d748a6e87b43db967fe338bcb08d74"}]},
+    ],
+    "last_seq":27}
+
+and we can change filter behavior with easy::
+
+    GET /somedatabase/_changes?filter=mailbox/by_status&status=spam HTTP/1.1
+
+.. code-block:: javascript
+
+    {"results":[
+    {"seq":11,"id":"8960e91220798fc9f9d29d24ed612e0d","changes":[{"rev":"3-cc6ff71af716ddc2ba114967025c0ee0"}]},
+    ],
+    "last_seq":27}
+
+
+Combining filters with `continuous` feed allows to create powerful event-driven
+systems.
+
+View filters
+------------
+
+View filters are the same as classic one with one small difference: they used
+view map function instead to filter changes feed. Each time a value could be
+emitted, a change is returned. This allows to avoid creating filter functions
+that are mostly does same works as views.
+
+To use them just specify `_view` value for ``filter`` parameter and
+`designdoc/viewname` for ``view`` one::
+
+    GET /somedatabase/_changes?filter=_view&view=dname/viewname  HTTP/1.1
+
+.. note:: Since view filters are uses map function as filter they couldn't have
+   dynamic behavior since :ref:`request object<request_object>` is not available
+
+.. _section in the book: http://books.couchdb.org/relax/reference/change-notifications

http://git-wip-us.apache.org/repos/asf/couchdb/blob/03fde1da/share/doc/src/json-structure.rst
----------------------------------------------------------------------
diff --git a/share/doc/src/json-structure.rst b/share/doc/src/json-structure.rst
index b0a88b5..f4fd4cc 100644
--- a/share/doc/src/json-structure.rst
+++ b/share/doc/src/json-structure.rst
@@ -109,6 +109,8 @@ CouchDB Error Status
 | reason                         | Error string with extended reason           |
 +--------------------------------+---------------------------------------------+
 
+.. _dbinfo_object:
+
 CouchDB database information object
 ===================================
 
@@ -332,6 +334,150 @@ Replication Status
 |     missing_found              | Number of missing documents found           |
 +--------------------------------+---------------------------------------------+
 
+.. _request_object:
+
+Request object
+==============
+
++--------------------------------+---------------------------------------------+
+| Field                          | Description                                 |
++================================+=============================================+
+| body                           | Request body data as `string`.              |
+|                                | If request method is `GET` method contains  |
+|                                | this field contains ``"undefined"`` value,  |
+|                                | while if `DELETE` or `HEAD` value is ``""`` |
+|                                | (empty string)                              |
++--------------------------------+---------------------------------------------+
+| cookie                         | Cookies `object`.                           |
+|                                | If request method is `GET` method contains  |
+|                                | this field contains ``"undefined"`` value,  |
+|                                | while if `DELETE` or `HEAD` value is ``""`` |
+|                                | (empty string).                             |
++--------------------------------+---------------------------------------------+
+| form                           | Form data `object`.                         |
+|                                | Contains decoded body as key-value pairs if |
+|                                | `Content-Type` header was                   |
+|                                | ``application/x-www-form-urlencoded``.      |
++--------------------------------+---------------------------------------------+
+| headers                        | Request headers `object`.                   |
++--------------------------------+---------------------------------------------+
+| id                             | Requested document id `string` if it was    |
+|                                | specified or ``null`` otherwise.            |
++--------------------------------+---------------------------------------------+
+| info                           | :ref:`Database information <dbinfo_object>` |
++--------------------------------+---------------------------------------------+
+| method                         | Request method as `string` or `array`.      |
+|                                | String value is method is one of: `HEAD`,   |
+|                                | `GET`, `POST`, `PUT`, `DELETE`, `OPTIONS`,  |
+|                                | and `TRACE`, otherwise it will be           |
+|                                | represented as array of char codes.         |
++--------------------------------+---------------------------------------------+
+| path                           | List of requested path sections.            |
++--------------------------------+---------------------------------------------+
+| peer                           | Request source IP address.                  |
++--------------------------------+---------------------------------------------+
+| query                          | URL query parameters `object`.              |
+|                                | Note that multiple keys not supported and   |
+|                                | last key value suppress others.             |
++--------------------------------+---------------------------------------------+
+| requested_path                 | List of actual requested path section.      |
++--------------------------------+---------------------------------------------+
+| raw_path                       | Raw requested path `string`.                |
++--------------------------------+---------------------------------------------+
+| secObj                         | :ref:`security_object`.                     |
++--------------------------------+---------------------------------------------+
+| userCtx                        | :ref:`userctx_object`.                      |
++--------------------------------+---------------------------------------------+
+| uuid                           | Generated UUID by specified algorithm in    |
+|                                | config file.                                |
++--------------------------------+---------------------------------------------+
+
+.. versionadded:: 0.9.0
+.. versionchanged:: 0.10.0 Add ``userCtx`` field.
+.. versionchanged:: 0.11.0 Rename ``verb`` field to ``method``.
+.. versionchanged:: 0.11.0 Add ``id``, ``peer`` and ``uuid`` fields.
+.. versionchanged:: 1.1.0 Add ``requested_path`` and ``secObj`` fields.
+.. versionchanged:: 1.2.0 Add ``raw_path`` field.
+
+.. code-block:: javascript
+
+  {
+      "body": "undefined",
+      "cookie": {
+          "AuthSession": "cm9vdDo1MDZBRjQzRjrfcuikzPRfAn-EA37FmjyfM8G8Lw",
+          "m": "3234"
+      },
+      "form": {},
+      "headers": {
+          "Accept": "text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8",
+          "Accept-Charset": "ISO-8859-1,utf-8;q=0.7,*;q=0.3",
+          "Accept-Encoding": "gzip,deflate,sdch",
+          "Accept-Language": "en-US,en;q=0.8",
+          "Connection": "keep-alive",
+          "Cookie": "m=3234:t|3247:t|6493:t|6967:t|34e2:|18c3:t|2c69:t|5acb:t|ca3:t|c01:t|5e55:t|77cb:t|2a03:t|1d98:t|47ba:t|64b8:t|4a01:t;
AuthSession=cm9vdDo1MDZBRjQzRjrfcuikzPRfAn-EA37FmjyfM8G8Lw",
+          "Host": "127.0.0.1:5984",
+          "User-Agent": "Mozilla/5.0 (Windows NT 5.2) AppleWebKit/535.7 (KHTML, like Gecko)
Chrome/16.0.912.75 Safari/535.7"
+      },
+      "id": "foo",
+      "info": {
+          "committed_update_seq": 2701412,
+          "compact_running": false,
+          "data_size": 7580843252,
+          "db_name": "mailbox",
+          "disk_format_version": 6,
+          "disk_size": 14325313673,
+          "doc_count": 2262757,
+          "doc_del_count": 560,
+          "instance_start_time": "1347601025628957",
+          "purge_seq": 0,
+          "update_seq": 2701412
+      },
+      "method": "GET",
+      "path": [
+          "mailbox",
+          "_design",
+          "request",
+          "_show",
+          "dump",
+          "foo"
+      ],
+      "peer": "127.0.0.1",
+      "query": {},
+      "raw_path": "/mailbox/_design/request/_show/dump/foo",
+      "requested_path": [
+          "mailbox",
+          "_design",
+          "request",
+          "_show",
+          "dump",
+          "foo"
+      ],
+      "secObj": {
+          "admins": {
+              "names": [
+                  "Bob"
+              ],
+              "roles": []
+          },
+          "members": {
+              "names": [
+                  "Mike",
+                  "Alice"
+              ],
+              "roles": []
+          }
+      },
+      "userCtx": {
+          "db": "mailbox",
+          "name": "Mike",
+          "roles": [
+              "user"
+          ]
+      },
+      "uuid": "3184f9d1ea934e1f81a24c71bde5c168"
+  }
+
+
 Returned CouchDB Document with Detailed Revision Info
 =====================================================
 
@@ -393,6 +539,8 @@ Returned Document with Attachments
 |         revpos                 | Revision where this attachment exists       |
 +--------------------------------+---------------------------------------------+
 
+.. _security_object:
+
 Security Object
 ===============
 
@@ -411,3 +559,48 @@ Security Object
 +--------------------------------+---------------------------------------------+
 |         users [array]          | List of users with parent privilege         |
 +--------------------------------+---------------------------------------------+
+
+.. code-block:: javascript
+
+  {
+      "admins": {
+          "names": [
+              "Bob"
+          ],
+          "roles": []
+      },
+      "members": {
+          "names": [
+              "Mike",
+              "Alice"
+          ],
+          "roles": []
+      }
+    }
+
+
+.. _userctx_object:
+
+User Context Object
+===================
+
++--------------------------------+---------------------------------------------+
+| Field                          | Description                                 |
++================================+=============================================+
+| db                             | Database name in context of provided        |
+|                                | operation.                                  |
++--------------------------------+---------------------------------------------+
+| name                           | User name.                                  |
++--------------------------------+---------------------------------------------+
+| roles                          | List of user roles.                         |
++--------------------------------+---------------------------------------------+
+
+.. code-block:: javascript
+
+    {
+        "db": "mailbox",
+        "name": null,
+        "roles": [
+            "_admin"
+        ]
+    }


Mime
View raw message