| {% include anchor.html title="Listen to database changes" hash="changes" %} |
| |
| {% highlight js %} |
| db.changes(options) |
| {% endhighlight %} |
| |
| A list of changes made to documents in the database, in the order they were made. |
| It returns an object with the method `cancel()`, which you call if you don't want to listen to new changes anymore. |
| |
| It is an [event emitter][event emitter] and will emit a `'change'` event on each document change, a `'complete'` event when all the changes have been processed, and an `'error'` event when an error occurs. In addition to the `'change'` event, any change will also emit a `'create'`, `'update'`, or `'delete'` event. |
| |
| ### Options |
| |
| All options default to `false` unless otherwise specified. |
| |
| * `options.include_docs`: Include the associated document with each change. |
| * `options.conflicts`: Include conflicts. |
| * `options.attachments`: Include attachments. |
| * `options.descending`: Reverse the order of the output documents. |
| * `options.since`: Start the results from the change immediately after the given sequence number. You can also pass 'now' if you want only new changes (when `live` is `true`). |
| * `options.live`: Uses the `_longpoll_` feed. |
| * `options.timeout`: Request timeout (in milliseconds). |
| * `options.limit`: Limit the number of results to this number. |
| * `options.doc_ids`: Only show changes for docs with these ids (array of strings). |
| * `options.filter`: Reference a filter function from a design document to selectively get updates. To use a view function, pass `_view` here and provide a reference to the view function in `options.view`. |
| * `options.query_params`: Object containing properties that are passed to the filter function, e.g. `{"foo:"bar"}`, where `"bar"` will be available in the filter function as `params.query.foo`. To access the `params`, define your filter function like `function (doc, params) {/* ... */}`. |
| * `options.view`: Specify a view function (e.g. `'design_doc_name/view_name'`) to act as a filter. Documents counted as "passed" for a view filter if a map function emits at least one record for them. **Note**: `options.filter` must be set to `'_view'` for this option to work. |
| * `options.returnDocs`: Is available for non-http databases and defaults to `true`. Passing `false` prevents the changes feed from keeping all the documents in memory – in other words complete always has an empty results array, and the `change` event is the only way to get the event. Useful for large change sets where otherwise you would run out of memory. |
| * `options.batch_size`: Only available for http databases, this configures how many changes to fetch at a time. Increasing this can reduce the number of requests made. Default is 25. |
| * `options.style`: 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). Most likely you won't need this unless you're writing a replicator. |
| |
| #### Example Usage: |
| |
| {% highlight js %} |
| var changes = db.changes({ |
| since: 'now', |
| live: true, |
| include_docs: true |
| }).on('change', function(change) { |
| // handle change |
| }).on('complete', function(info) { |
| // changes() was canceled |
| }).on('error', function (err) { |
| console.log(err); |
| }); |
| |
| changes.cancel(); // whenever you want to cancel |
| {% endhighlight %} |
| |
| #### Example Response: |
| {% highlight js %} |
| { |
| "id":"somestuff", |
| "seq":21, |
| "changes":[{ |
| "rev":"1-8e6e4c0beac3ec54b27d1df75c7183a8" |
| }], |
| "doc":{ |
| "title":"Ch-Ch-Ch-Ch-Changes", |
| "_id":"someDocId", |
| "_rev":"1-8e6e4c0beac3ec54b27d1df75c7183a8" |
| } |
| } |
| {% endhighlight %} |
| |
| #### Change events |
| |
| * __`change`__ (`info`) - This event fires when a change has been found. `info` will contain details about the change, such as whether it was deleted and what the new `_rev` is. `info.doc` will contain the doc if you set `include_docs` to `true`. See below for an example response. |
| * __`complete`__ (`info`) - This event fires when all changes have been read. In live changes, only cancelling the changes should trigger this event. `info.results` will contain the list of changes. See below for an example. |
| * __`error`__ (`err`) - This event is fired when the replication is stopped due to an unrecoverable failure. |
| |
| #### Example response |
| |
| Example response in the `'change'` listener (using `{include_docs: true}`): |
| |
| {% highlight js %} |
| { id: 'doc1', |
| changes: [ { rev: '1-9152679630cc461b9477792d93b83eae' } ], |
| doc: { |
| _id: 'doc1', |
| _rev: '1-9152679630cc461b9477792d93b83eae' |
| }, |
| seq: 1 |
| } |
| {% endhighlight %} |
| |
| Example response in the `'change'` listener when a doc was deleted: |
| |
| {% highlight js %} |
| { id: 'doc2', |
| changes: [ { rev: '2-9b50a4b63008378e8d0718a9ad05c7af' } ], |
| doc: { _id: 'doc2', |
| _rev: '2-9b50a4b63008378e8d0718a9ad05c7af', |
| _deleted: true |
| }, |
| deleted: true, |
| seq: 3 |
| } |
| {% endhighlight %} |
| |
| Example response in the `'complete'` listener: |
| |
| {% highlight js %} |
| { |
| "results": [ |
| { |
| "id": "doc1", |
| "changes": [ { "rev": "1-9152679630cc461b9477792d93b83eae" } ], |
| "doc": { |
| "_id": "doc1", |
| "_rev": "1-9152679630cc461b9477792d93b83eae" |
| }, |
| "seq": 1 |
| }, |
| { |
| "id": "doc2", |
| "changes": [ { "rev": "2-9b50a4b63008378e8d0718a9ad05c7af" } ], |
| "doc": { |
| "_id": "doc2", |
| "_rev": "2-9b50a4b63008378e8d0718a9ad05c7af", |
| "_deleted": true |
| }, |
| "deleted": true, |
| "seq": 3 |
| } |
| ], |
| "last_seq": 3 |
| } |
| {% endhighlight %} |
| |
| `seq` and `last_seq` correspond to the overall sequence number of the entire database, and it's what is passed in when using `since` (except for the special `'now'`). It is the primary key for the changes feed, and is also used as a checkpointer by the replication algorithm. |
| |
| #### Single-shot |
| |
| If you don't specify `{live: true}`, then you can also use `changes()` in the standard |
| callback/promise style, and it will be treated as a single-shot request, which |
| returns a list of the changes (i.e. what the `'complete'` event emits): |
| |
| {% include code/start.html id="changes1" type="callback" %} |
| {% highlight js %} |
| db.changes({ |
| limit: 10, |
| since: 0 |
| }, function (err, response) { |
| if (err) { return console.log(err); } |
| // handle result |
| }); |
| {% endhighlight %} |
| {% include code/end.html %} |
| {% include code/start.html id="changes1" type="promise" %} |
| {% highlight js %} |
| db.changes({ |
| limit: 10, |
| since: 0 |
| }).then(function (result) { |
| // handle result |
| }).catch(function (err) { |
| console.log(err); |
| }); |
| {% endhighlight %} |
| {% include code/end.html %} |
| |
| #### Example Response: |
| |
| {% highlight js %} |
| { |
| "results": [{ |
| "id": "0B3358C1-BA4B-4186-8795-9024203EB7DD", |
| "seq": 1, |
| "changes": [{ |
| "rev": "1-5782E71F1E4BF698FA3793D9D5A96393" |
| }] |
| }, { |
| "id": "mydoc", |
| "seq": 2, |
| "changes": [{ |
| "rev": "1-A6157A5EA545C99B00FF904EEF05FD9F" |
| }] |
| }, { |
| "id": "otherdoc", |
| "seq": 3, |
| "changes": [{ |
| "rev": "1-3753476B70A49EA4D8C9039E7B04254C" |
| }] |
| }, { |
| "id": "828124B9-3973-4AF3-9DFD-A94CE4544005", |
| "seq": 4, |
| "changes": [{ |
| "rev": "1-A8BC08745E62E58830CA066D99E5F457" |
| }] |
| }] |
| } |
| {% endhighlight %} |
| |
| When `live` is `false`, the returned object is also an event emitter as well as a promise, |
| and will fire the `'complete'` event when the results are ready. |
| |
| Note that this `'complete'` event only fires when you aren't doing live changes. With live changes, use the `'paused'` event instead. |