blob: fbc02e46d97e621eb855d2cb339d2e49976e3a75 [file] [log] [blame]
{% 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.