/{db}/_changes
-
GET/{db}/_changes -
Возвращает отсортированный список изменений, внесённых в документы базы данных, в порядке их применения. Гарантируется предоставление только последнего изменения для каждого документа. Например, если в документ были добавлены, а затем удалены поля, клиент API, отслеживающий изменения, не обязательно получит промежуточное состояние с добавленными полями.
Это можно использовать для отслеживания обновлений и изменений базы данных с целью последующей обработки или синхронизации. Для большинства приложений непрерывно подключённый поток
_changes— разумный способ создания журнала событий в реальном времени.- Параметры:
-
db – Имя базы данных
- Заголовки запроса:
-
-
Accept –
application/json
text/event-stream
text/plain
Last-Event-ID – Идентификатор последних событий, полученных сервером при предыдущем соединении. Переопределяет параметр запроса
since.
-
- Параметры запроса:
-
doc_ids (array) – Список идентификаторов документов для фильтрации потока изменений в виде допустимого массива JSON. Используется с фильтром _doc_ids. Поскольку длина URL ограничена, вместо этого лучше использовать
POST /{db}/_changes.conflicts (boolean) – Включает в ответ информацию о conflicts. Игнорируется, если
trueдля параметра include_docs не задано. По умолчанию —false.descending (boolean) – Возвращает результаты изменений в порядке убывания последовательности (сначала самое недавнее изменение). По умолчанию —
false.-
feed (string) –
normal Указывает обычный режим опроса. Все прошлые изменения возвращаются сразу. По умолчанию.
longpoll Указывает режим длительного опроса. Ожидает появления хотя бы одного изменения, отправляет его, а затем закрывает соединение. Чаще всего используется вместе с
since=nowдля ожидания следующего изменения.continuous Включает непрерывный режим. Отправляет строку JSON для каждого события. Сохраняет сокет открытым до
timeout.eventsource Включает режим источника событий. Работает так же, как непрерывный режим, но отправляет события в формате EventSource.
-
filter (string) –
design_doc/filter_name Ссылка на функцию фильтра из документа проектирования, которая фильтрует весь поток, отправляя только отобранные события. Дополнительные сведения см. в разделе «Уведомления об изменениях» в книге CouchDB The Definitive Guide.
_doc_ids фильтр doc_ids
_view фильтр представления
_design фильтр документов проектирования
heartbeat (number) – Интервал в миллисекундах, по истечении которого в результатах отправляется пустая строка. Применяется только для потоков longpoll, continuous и eventsource. Переопределяет любой тайм-аут, чтобы поток оставался активным неограниченно долго. По умолчанию —
60000. Можно задатьtrue, чтобы использовать значение по умолчанию.include_docs (boolean) – Включает соответствующий документ в каждый результат. При наличии конфликтов возвращается только победившая ревизия. По умолчанию —
false. При использовании со стилемall_docsи фильтром возвращает тело документа, даже если оно не соответствует критериям фильтрации. Иными словами, фильтрация применяется только к списку ревизий"changes", а не к возвращаемому телу документа в поле"doc".attachments (boolean) – Включает содержимое вложений в кодировке Base64 в документы, если
include_docsимеет значениеtrue. Игнорируется, еслиinclude_docsне имеет значенияtrue. По умолчанию —false.att_encoding_info (boolean) – Включает информацию о кодировке в заглушки вложений, если
include_docsимеет значениеtrue, а соответствующее вложение сжато. Игнорируется, еслиinclude_docsне имеет значенияtrue. По умолчанию —false.last-event-id (number) – Псевдоним заголовка Last-Event-ID.
limit (number) – Ограничивает количество строк результата указанным значением (обратите внимание: использование здесь
0даёт тот же эффект, что и1).since – Начинает выдачу результатов с изменения, следующего за указанной последовательностью обновления. Допустимое значение — последовательность обновления или
now. По умолчанию —0.style (string) – Определяет количество ревизий, возвращаемых в массиве changes. Значение по умолчанию,
main_only, возвращает только текущую «победившую» ревизию;all_docsвозвращает все конечные ревизии (включая конфликты и удалённые бывшие конфликты). При использовании фильтра со стилемall_docsстрока changes пропускается, если ни одна из ревизий не соответствует фильтру. Если соответствует хотя бы одна ревизия, строка changes возвращается со всеми подходящими ревизиями. Если стильall_docsиспользуется сinclude_docs=trueи фильтру соответствует хотя бы одна ревизия, возвращается тело победившего документа, даже если оно не соответствует критериям фильтрации.timeout (number) – Максимальное время ожидания изменения в миллисекундах, по истечении которого отправляется ответ, даже если результатов нет. Применяется только для потоков longpoll, continuous или eventsource. Значение по умолчанию задаётся параметром конфигурации
chttpd/changes_timeout. Обратите внимание: значение60000также является максимальным тайм-аутом по умолчанию, предотвращающим обнаружение разорванных соединений.view (string) – Позволяет использовать функции представления в качестве фильтров. Документы считаются прошедшими фильтр представления, если функция map выдаёт для них хотя бы одну запись. Дополнительные сведения см. в разделе _view.
seq_interval (number) – При получении изменений пакетами параметр seq_interval указывает CouchDB вычислять последовательность обновления только для каждого N-го возвращаемого результата. Если задать seq_interval=<batch size>, где
<batch size>— количество результатов, запрашиваемых в каждом пакете, можно снизить нагрузку на исходную базу данных CouchDB. Вычисление значения seq по множеству шардов (особенно в базах данных с большим количеством шардов) требует значительных ресурсов в сильно загруженном кластере CouchDB.
- Заголовки ответа:
-
Cache-Control –
no-cache, если поток изменений имеет тип eventsource-
application/json
text/event-stream
text/plain; charset=utf-8
ETag – Хеш ответа, если поток изменений имеет тип normal
Transfer-Encoding –
chunked
- Объект JSON ответа:
-
last_seq (json) – Последовательность последнего обновления
pending (number) – Количество оставшихся элементов в потоке
results (array) – Изменения, внесённые в базу данных
- Коды состояния:
-
200 OK – Запрос успешно выполнен
400 Bad Request – Некорректный запрос
401 Unauthorized – Неавторизованный запрос к защищённому API
403 Forbidden – Недостаточно прав / Слишком много запросов с недействительными учётными данными
Поле
resultsизменений базы данных:- Параметры JSON:
-
changes (array) – Список конечных ревизий документа с единственным полем
rev.id (string) – Идентификатор документа.
seq (json) – Последовательность обновления.
deleted (bool) –
true, если документ удалён.
Запрос:
GET /db/_changes?style=all_docs HTTP/1.1 Accept: application/json Host: localhost:5984
Ответ:
HTTP/1.1 200 OK Cache-Control: must-revalidate Content-Type: application/json Date: Mon, 12 Aug 2013 00:54:58 GMT ETag: "6ASLEKEMSRABT0O5XY9UPO9Z" Server: CouchDB (Erlang/OTP) Transfer-Encoding: chunked { "last_seq": "5-g1AAAAIreJyVkEsKwjAURZ-toI5cgq5A0sQ0OrI70XyppcaRY92J7kR3ojupaSPUUgotgRd4yTlwbw4A0zRUMLdnpaMkwmyF3Ily9xBwEIuiKLI05KOTW0wkV4rruP29UyGWbordzwKVxWBNOGMKZhertDlarbr5pOT3DV4gudUC9-MPJX9tpEAYx4TQASns2E24ucuJ7rXJSL1BbEgf3vTwpmedCZkYa7Pulck7Xt7x_usFU2aIHOD4eEfVTVA5KMGUkqhNZV-8_o5i", "pending": 0, "results": [ { "changes": [ { "rev": "2-7051cbe5c8faecd085a3fa619e6e6337" } ], "id": "6478c2ae800dfc387396d14e1fc39626", "seq": "3-g1AAAAG3eJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P___7MSGXAqSVIAkkn2IFUZzIkMuUAee5pRqnGiuXkKA2dpXkpqWmZeagpu_Q4g_fGEbEkAqaqH2sIItsXAyMjM2NgUUwdOU_JYgCRDA5ACGjQfn30QlQsgKvcjfGaQZmaUmmZClM8gZhyAmHGfsG0PICrBPmQC22ZqbGRqamyIqSsLAAArcXo" }, { "changes": [ { "rev": "3-7379b9e515b161226c6559d90c4dc49f" } ], "deleted": true, "id": "5bbc9ca465f1b0fcd62362168a7c8831", "seq": "4-g1AAAAHXeJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P___7MymBMZc4EC7MmJKSmJqWaYynEakaQAJJPsoaYwgE1JM0o1TjQ3T2HgLM1LSU3LzEtNwa3fAaQ_HqQ_kQG3qgSQqnoUtxoYGZkZG5uS4NY8FiDJ0ACkgAbNx2cfROUCiMr9CJ8ZpJkZpaaZEOUziBkHIGbcJ2zbA4hKsA-ZwLaZGhuZmhobYurKAgCz33kh" }, { "changes": [ { "rev": "6-460637e73a6288cb24d532bf91f32969" }, { "rev": "5-eeaa298781f60b7bcae0c91bdedd1b87" } ], "id": "729eb57437745e506b333068fff665ae", "seq": "5-g1AAAAIReJyVkE0OgjAQRkcwUVceQU9g-mOpruQm2tI2SLCuXOtN9CZ6E70JFmpCCCFCmkyTdt6bfJMDwDQNFcztWWkcY8JXyB2cu49AgFwURZGloRid3MMkEUoJHbXbOxVy6arc_SxQWQzRVHCuYHaxSpuj1aqbj0t-3-AlSrZakn78oeSvjRSIkIhSNiCFHbsKN3c50b02mURvEB-yD296eNOzzoRMRLRZ98rkHS_veGcC_nR-fGe1gaCaxihhjOI2lX0BhniHaA" } ] }
Изменено в версии 0.11.0: добавлен параметр include_docs
Изменено в версии 1.2.0: добавлен параметр view и специальное значение _view для filter
Изменено в версии 1.3.0: параметр since может принимать значение now, чтобы начать прослушивание изменений с текущего номера последовательности.
Изменено в версии 1.3.0: добавлен тип потока eventsource.
Изменено в версии 1.4.0: Добавлена поддержка заголовка Last-Event-ID.
Изменено в версии 1.6.0: добавлены параметры attachments и att_encoding_info
Изменено в версии 2.0.0: последовательности обновления могут быть любым допустимым объектом JSON, добавлен seq_interval
Примечание
Если указанные реплики шардов для какого-либо значения since недоступны, выбираются альтернативные реплики и используется последняя известная контрольная точка между ними. В этом случае вы можете снова увидеть изменения, которые уже получали ранее. Поэтому приложение, использующее поток _changes, должно быть «идемпотентным», то есть безопасно обрабатывать одни и те же данные несколько раз.
Примечание
Cloudant Sync и PouchDB уже оптимизируют процесс репликации, задавая параметру seq_interval количество результатов, ожидаемых в каждом пакете. Этот параметр повышает пропускную способность, сокращая задержку между последовательными запросами при массовой передаче документов. Это позволило повысить производительность репликации до 20 % в базах данных с большим количеством шардов.
Предупреждение
Не рекомендуется использовать параметр attachments для включения вложений в поток изменений, если вложения имеют большой размер. Также учтите, что кодирование Base64 увеличивает размер передаваемых вложений на 33 % (то есть на одну треть).
Предупреждение
Результаты, возвращаемые _changes, упорядочены лишь частично. Иными словами, порядок не гарантирован для нескольких вызовов.
-
POST/{db}/_changes -
Запрашивает поток изменений базы данных так же, как это делает
GET /{db}/_changes, но широко используется с параметрами запроса?filter=_doc_idsили?filter=_selectorи позволяет передавать более длинный список идентификаторов документов или тело селектора для фильтрации.- Параметры:
-
db – Имя базы данных
- Параметры запроса:
-
-
filter (string) –
_doc_ids фильтр doc_ids
_selector фильтр selector
-
Запрос:
POST /recipes/_changes?filter=_doc_ids HTTP/1.1 Accept: application/json Content-Length: 40 Content-Type: application/json Host: localhost:5984 { "doc_ids": [ "SpaghettiWithMeatballs" ] }Ответ:
HTTP/1.1 200 OK Cache-Control: must-revalidate Content-Type: application/json Date: Sat, 28 Sep 2013 07:23:09 GMT ETag: "ARIHFWL3I7PIS0SPVTFU6TLR2" Server: CouchDB (Erlang OTP) Transfer-Encoding: chunked { "last_seq": "5-g1AAAAIreJyVkEsKwjAURZ-toI5cgq5A0sQ0OrI70XyppcaRY92J7kR3ojupaSPUUgotgRd4yTlwbw4A0zRUMLdnpaMkwmyF3Ily9xBwEIuiKLI05KOTW0wkV4rruP29UyGWbordzwKVxWBNOGMKZhertDlarbr5pOT3DV4gudUC9-MPJX9tpEAYx4TQASns2E24ucuJ7rXJSL1BbEgf3vTwpmedCZkYa7Pulck7Xt7x_usFU2aIHOD4eEfVTVA5KMGUkqhNZV8_o5i", "pending": 0, "results": [ { "changes": [ { "rev": "13-bcb9d6388b60fd1e960d9ec4e8e3f29e" } ], "id": "SpaghettiWithMeatballs", "seq": "5-g1AAAAIReJyVkE0OgjAQRkcwUVceQU9g-mOpruQm2tI2SLCuXOtN9CZ6E70JFmpCCCFCmkyTdt6bfJMDwDQNFcztWWkcY8JXyB2cu49AgFwURZGloRid3MMkEUoJHbXbOxVy6arc_SxQWQzRVHCuYHaxSpuj1aqbj0t-3-AlSrZakn78oeSvjRSIkIhSNiCFHbsKN3c50b02mURvEB-yD296eNOzzoRMRLRZ98rkHS_veGcC_nR-fGe1gaCaxihhjOI2lX0BhniHaA" } ] }Запрос:
POST /db/_changes?filter=_selector HTTP/1.1 Accept: application/json Accept-Encoding: gzip, deflate Content-Length: 25 Content-Type: application/json Host: 127.0.0.1:5984 { "selector": { "data": 1 } }Ответ:
HTTP/1.1 200 OK Cache-Control: must-revalidate Content-Type: application/json Date: Fri, 05 Jan 2024 18:08:46 GMT ETag: "9UTJJV90GMV3XQKBM9RNAS0IK" Server: CouchDB/3.3.3-42c2484 (Erlang OTP/24) Transfer-Encoding: chunked { "last_seq": "4-g1AAAACTeJzLYWBgYMpgTmHgz8tPSTV0MDQy1zMAQsMckEQiQ1L9____szKYE5lzgQLshqkGSWmGyZjKcRqRxwIkGRqA1H-oSYxgk0ySLSxSEi0wdWUBAGlCJKQ", "pending": 0, "results": [ { "changes": [ { "rev": "3-fc9d7a5cf38c9f062aa246cb072eae68" } ], "id": "d1", "seq": "4-g1AAAACTeJzLYWBgYMpgTmHgz8tPSTV0MDQy1zMAQsMckEQiQ1L9____szKYE5lzgQLshqkGSWmGyZjKcRqRxwIkGRqA1H-oSYxgk0ySLSxSEi0wdWUBAGlCJKQ" } ] }
Потоки изменений
Опрос
По умолчанию все изменения сразу возвращаются в теле JSON:
GET /somedatabase/_changes HTTP/1.1
{"results":[
{"seq":"1-g1AAAAF9eJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P__7MSGXAqSVIAkkn2IFUZzIkMuUAee5pRqnGiuXkKA2dpXkpqWmZeagpu_Q4g_fGEbEkAqaqH2sIItsXAyMjM2NgUUwdOU_JYgCRDA5ACGjQfn30QlQsgKvcTVnkAovI-YZUPICpBvs0CAN1eY_c","id":"fresh","changes":[{"rev":"1-967a00dff5e02add41819138abb3284d"}]},
{"seq":"3-g1AAAAG3eJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P___7MSGXAqSVIAkkn2IFUZzIkMuUAee5pRqnGiuXkKA2dpXkpqWmZeagpu_Q4g_fGEbEkAqaqH2sIItsXAyMjM2NgUUwdOU_JYgCRDA5ACGjQfn30QlQsgKvcjfGaQZmaUmmZClM8gZhyAmHGfsG0PICrBPmQC22ZqbGRqamyIqSsLAAArcXo","id":"updated","changes":[{"rev":"2-7051cbe5c8faecd085a3fa619e6e6337CFCmkyTdt6bfJMDwDQNFcztWWkcY8JXyB2cu49AgFwURZGloRid3MMkEUoJHbXbOxVy6arc_SxQWQzRVHCuYHaxSpuj1aqbj0t-3-AlSrZakn78oeSvjRSIkIhSNiCFHbsKN3c50b02mURvEB-yD296eNOzzoRMRLRZ98rkHS_veGcC_nR-fGe1gaCaxihhjOI2lX0BhniHaA","id":"deleted","changes":[{"rev":"2-eec205a9d413992850a6e32678485900"}],"deleted":true}
],
"last_seq":"5-g1AAAAIreJyVkEsKwjAURZ-toI5cgq5A0sQ0OrI70XyppcaRY92J7kR3ojupaSPUUgotgRd4yTlwbw4A0zRUMLdnpaMkwmyF3Ily9xBwEIuiKLI05KOTW0wkV4rruP29UyGWbordzwKVxWBNOGMKZhertDlarbr5pOT3DV4gudUC9-MPJX9tpEAYx4TQASns2E24ucuJ7rXJSL1BbEgf3vTwpmedCZkYa7Pulck7Xt7x_usFU2aIHOD4eEfVTVA5KMGUkqhNZV-8_o5i",
"pending": 0} results — список изменений в последовательном порядке. Новые и изменённые документы отличаются только значением rev; удалённые документы содержат атрибут "deleted": true. (В style=all_docs mode признак deleted применяется только к текущей/победившей ревизии. Другие перечисленные ревизии могут быть удалены, даже если свойства deleted нет; чтобы убедиться в этом, необходимо GET каждую из них отдельно.)
last_seq — последовательность обновления последнего возвращённого обновления (эквивалентна последнему элементу в results).
Передача параметра since в строке запроса пропускает все изменения вплоть до указанной последовательности обновления включительно:
GET /somedatabase/_changes?since=4-g1AAAAHXeJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P___7MymBMZc4EC7MmJKSmJqWaYynEakaQAJJPsoaYwgE1JM0o1TjQ3T2HgLM1LSU3LzEtNwa3fAaQ_HqQ_kQG3qgSQqnoUtxoYGZkZG5uS4NY8FiDJ0ACkgAbNx2cfROUCiMr9CJ8ZpJkZpaaZEOUziBkHIGbcJ2zbA4hKsA-ZwLaZGhuZmhobYurKAgCz33kh HTTP/1.1
Структура ответа для режимов normal и longpoll — это массив JSON объектов изменений и последовательность последнего обновления.
В формате ответа для режима continuous сервер отправляет строку, разделённую CRLF (возвратом каретки и переводом строки), для каждого изменения. Каждая строка содержит описанный выше объект JSON.
Также можно запросить полное содержимое каждого изменённого документа (вместо одного лишь уведомления об изменении), используя параметр include_docs.
{
"last_seq": "5-g1AAAAIreJyVkEsKwjAURZ-toI5cgq5A0sQ0OrI70XyppcaRY92J7kR3ojupaSPUUgotgRd4yTlwbw4A0zRUMLdnpaMkwmyF3Ily9xBwEIuiKLI05KOTW0wkV4rruP29UyGWbordzwKVxWBNOGMKZhertDlarbr5pOT3DV4gudUC9-MPJX9tpEAYx4TQASns2E24ucuJ7rXJSL1BbEgf3vTwpmedCZkYa7Pulck7Xt7x_usFU2aIHOD4eEfVTVA5KMGUkqhNZV-8_o5i",
"pending": 0,
"results": [
{
"changes": [
{
"rev": "2-eec205a9d413992850a6e32678485900"
}
],
"deleted": true,
"id": "deleted",
"seq": "5-g1AAAAIReJyVkE0OgjAQRkcwUVceQU9g-mOpruQm2tI2SLCuXOtN9CZ6E70JFmpCCCFCmkyTdt6bfJMDwDQNFcztWWkcY8JXyB2cu49AgFwURZGloRid3MMkEUoJHbXbOxVy6arc_SxQWQzRVHCuYHaxSpuj1aqbj0t-3-AlSrZakn78oeSvjRSIkIhSNiCFHbsKN3c50b02mURvEByD296eNOzzoRMRLRZ98rkHS_veGcC_nR-fGe1gaCaxihhjOI2lX0BhniHaA",
}
]
} Длительный опрос
Поток longpoll, вероятно, наиболее подходящий для браузера, — это более эффективный вариант опроса, при котором ответ отправляется только после появления изменения. longpoll избавляет от необходимости часто обращаться к CouchDB, чтобы выяснить, что ничего не изменилось!
Запрос к серверу остаётся открытым, пока в базе данных не произойдёт изменение и оно не будет передано, после чего соединение закрывается. Это создаёт небольшую нагрузку и на сервер, и на клиент.
Ответ представляет собой практически такой же JSON, как и для потока normal.
Поскольку ожидание изменения может быть долгим, можно задать тайм-аут, по истечении которого соединение будет автоматически закрыто (аргумент timeout). Также можно задать интервал отправки сигнала активности (с помощью аргумента запроса heartbeat), который отправляет символ новой строки, чтобы соединение оставалось активным.
Помните, что heartbeat означает «Отправлять перевод строки каждые x мс, если изменений нет, и удерживать соединение открытым неограниченно долго», а timeout означает «Удерживать это соединение открытым x мс и закрыть сокет, если за это время не появится изменений». heartbeat переопределяет timeout.
Непрерывный режим
Постоянно опрашивать сервер CouchDB нецелесообразно: установка новых HTTP-соединений лишь для того, чтобы сообщить клиенту об отсутствии изменений, создаёт ненужную нагрузку на CouchDB.
Непрерывный поток остаётся открытым и подключённым к базе данных, пока его явно не закроют, а изменения отправляются клиенту по мере их появления, то есть почти в реальном времени.
Как и для типа потока longpoll, можно задать интервал тайм-аута и интервал отправки сигнала активности, чтобы соединение оставалось открытым для новых изменений и обновлений.
Помните, что heartbeat означает «Отправлять перевод строки каждые x мс, если изменений нет, и удерживать соединение открытым неограниченно долго», а timeout означает «Удерживать это соединение открытым x мс и закрыть сокет, если за это время не появится изменений». heartbeat переопределяет timeout.
Ответ непрерывного потока немного отличается от ответов других типов потока, что упрощает работу клиента: каждая строка ответа либо пуста, либо содержит объект JSON, представляющий одно изменение, как в массиве results обычного потока.
Если указан limit, поток завершается объектом { last_seq }.
GET /somedatabase/_changes?feed=continuous HTTP/1.1
{"seq":"1-g1AAAAF9eJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P___7MSGXAqSVIAkkn2IFUZzIkMuUAee5pRqnGiuXkKA2dpXkpqWmZeagpu_Q4g_fGEbEkAqaqH2sIItsXAyMjM2NgUUwdOU_JYgCRDA5ACGjQfn30QlQsgKvcTVnkAovI-YZUPICpBvs0CAN1eY_c","id":"fresh","changes":[{"rev":"5-g1AAAAHxeJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P___7MymBOZcoEC7MmJKSmJqWaYynEakaQAJJPsoaYwgE1JM0o1TjQ3T2HgLM1LSU3LzEtNwa3fAaQ_HkV_kkGyZWqSEXH6E0D666H6GcH6DYyMzIyNTUnwRR4LkGRoAFJAg-YjwiMtOdXCwJyU8ICYtABi0n6EnwzSzIxS00yI8hPEjAMQM-5nJTIQUPkAovI_UGUWAA0SgOI","id":"updated","changes":[{"rev":"2-7051cbe5c8faecd085a3fa619e6e6337"}]}
{"seq":"3-g1AAAAHReJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P___7MymBOZcoEC7MmJKSmJqWaYynEakaQAJJPsoaYwgE1JM0o1TjQ3T2HgLM1LSU3LzEtNwa3fAaQ_HkV_kkGyZWqSEXH6E0D660H6ExlwqspjAZIMDUAKqHA-yCZGiEuTUy0MzEnxL8SkBRCT9iPcbJBmZpSaZkKUmyFmHICYcZ-wux9AVIJ8mAUABgp6XQ","id":"deleted","changes":[{"rev":"2-eec205a9d413992850a6e32678485900"}],"deleted":true}
... tum tee tum ...
{"seq":"6-g1AAAAIreJyVkEsKwjAURWMrqCOXoCuQ9MU0OrI70XyppcaRY92J7kR3ojupaVNopRQsgRd4yTlwb44QmqahQnN7VjpKImAr7E6Uu4eAI7EoiiJLQx6c3GIiuVJcx93vvQqxdFPsaguqLAY04YwpNLtYpc3RatXPJyW__-EFllst4D_-UPLXmh9VPAaICaEDUtixm-jmLie6N30YqTeYDenDmx7e9GwyYRODNuu_MnnHyzverV6AMkPkAMfHO1rdUAKUkqhLZV-_0o5j","id":"updated","changes":[{"rev":"3-825cb35de44c433bfb2df415563a19de"}]} Разумеется, … tum tee tum … не появляется в реальном ответе, а обозначает длительную паузу перед изменением с seq 6.
Источник событий
Поток eventsource предоставляет push-уведомления, которые можно получать в браузере в виде событий DOM. Дополнительные сведения см. в спецификации W3C EventSource. CouchDB также учитывает параметр Last-Event-ID.
GET /somedatabase/_changes?feed=eventsource HTTP/1.1
// define the event handling function
if (window.EventSource) {
var source = new EventSource("/somedatabase/_changes?feed=eventsource");
source.onerror = function(e) {
alert('EventSource failed.');
};
var results = [];
var sourceListener = function(e) {
var data = JSON.parse(e.data);
results.push(data);
};
// start listening for events
source.addEventListener('message', sourceListener, false);
// stop listening for events
source.removeEventListener('message', sourceListener, false);
} Если задать интервал отправки сигнала активности (с помощью аргумента запроса heartbeat), CouchDB будет отправлять событие hearbeat, на которое можно подписаться следующим образом:
source.addEventListener('heartbeat', function () {}, false); Клиентское приложение может отслеживать это событие и при необходимости повторно устанавливать соединение EventSource (например, если TCP-соединение зависает в полуоткрытом состоянии).
Примечание
На соединения EventSource распространяются ограничения на совместное использование ресурсов между источниками. Возможно, потребуется настроить поддержку CORS, чтобы EventSource работал в приложении.
Фильтрация
Содержимое потока изменений можно фильтровать несколькими способами. Самый простой способ — указать в запросе один или несколько идентификаторов документов. В результате возвращаемая структура будет содержать изменения только для указанных идентификаторов. Обратите внимание: значение этого аргумента запроса должно быть массивом в формате JSON.
Поток _changes также можно фильтровать, определив функцию фильтра в документе проектирования. Спецификация фильтра такая же, как для фильтров репликации. Укажите имя функции фильтра в параметре filter, задав имя документа проектирования и имя фильтра. Например:
GET /db/_changes?filter=design_doc/filtername HTTP/1.1
Кроме того, доступны несколько встроенных фильтров, описанных ниже.
_doc_ids
Этот фильтр пропускает только изменения документов, идентификаторы которых указаны в параметре запроса doc_ids или в массиве объектов тела запроса. Пример см. в разделе POST /{db}/_changes.
_selector
Добавлено в версии 2.0.
Этот фильтр пропускает только изменения документов, соответствующих указанному селектору, заданному с помощью того же синтаксиса селекторов, что и для _find.
Этот способ значительно эффективнее использования функции фильтра на JavaScript и рекомендуется, если фильтрация выполняется только по атрибутам документа.
Обратите внимание: в отличие от фильтров JavaScript, селекторы не имеют доступа к объекту запроса.
Запрос:
POST /recipes/_changes?filter=_selector HTTP/1.1
Content-Type: application/json
Host: localhost:5984
{
"selector": { "_id": { "$regex": "^_design/" } }
} Ответ:
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Type: application/json
Date: Tue, 06 Sep 2016 20:03:23 GMT
Etag: "1H8RGBCK3ABY6ACDM7ZSC30QK"
Server: CouchDB (Erlang OTP/18)
Transfer-Encoding: chunked
{
"last_seq": "11-g1AAAAIreJyVkEEKwjAQRUOrqCuPoCeQZGIaXdmbaNIk1FLjyrXeRG-iN9Gb1LQRaimFlsAEJnkP_s8RQtM0VGhuz0qTmABfYXdI7h4CgeSiKIosDUVwcotJIpQSOmp_71TIpZty97OgymJAU8G5QrOLVdocrVbdfFzy-wYvcbLVEvrxh5K_NlJggIhSNiCFHbmJbu5yonttMoneYD6kD296eNOzzoRNBNqse2Xyjpd3vP96AcYNTQY4Pt5RdTOuHIwCY5S0qewLwY6OaA",
"pending": 0,
"results": [
{
"changes": [
{
"rev": "10-304cae84fd862832ea9814f02920d4b2"
}
],
"id": "_design/ingredients",
"seq": "8-g1AAAAHxeJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P___7MymBOZcoEC7MmJKSmJqWaYynEakaQAJJPsoaYwgE1JM0o1TjQ3T2HgLM1LSU3LzEtNwa3fAaQ_HkV_kkGyZWqSEXH6E0D666H6GcH6DYyMzIyNTUnwRR4LkGRoAFJAg-ZnJTIQULkAonI_ws0GaWZGqWkmRLkZYsYBiBn3Cdv2AKIS7ENWsG2mxkampsaGmLqyAOYpgEo"
},
{
"changes": [
{
"rev": "123-6f7c1b7c97a9e4f0d22bdf130e8fd817"
}
],
"deleted": true,
"id": "_design/cookbook",
"seq": "9-g1AAAAHxeJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P___7MymBOZcoEC7MmJKSmJqWaYynEakaQAJJPsoaYwgE1JM0o1TjQ3T2HgLM1LSU3LzEtNwa3fAaQ_HkV_kkGyZWqSEXH6E0D661F8YWBkZGZsbEqCL_JYgCRDA5ACGjQ_K5GBgMoFEJX7EW42SDMzSk0zIcrNEDMOQMy4T9i2BxCVYB-ygm0zNTYyNTU2xNSVBQDnK4BL"
},
{
"changes": [
{
"rev": "6-5b8a52c22580e922e792047cff3618f3"
}
],
"deleted": true,
"id": "_design/meta",
"seq": "11-g1AAAAIReJyVkE0OgjAQRiegUVceQU9g-mOpruQm2tI2SLCuXOtN9CZ6E70JFmpCCCFCmkyTdt6bfJMDwDQNFcztWWkcY8JXyB2cu49AgFwURZGloQhO7mGSCKWEjtrtnQq5dFXufhaoLIZoKjhXMLtYpc3RatXNxyW_b_ASJVstST_-UPLXRgpESEQpG5DCjlyFm7uc6F6bTKI3iA_Zhzc9vOlZZ0ImItqse2Xyjpd3vDMBfzo_vrPawLiaxihhjOI2lX0BirqHbg"
}
]
} Отсутствует селектор
Если объект селектора отсутствует в теле запроса, сообщение об ошибке будет выглядеть примерно так:
{
"error": "bad request",
"reason": "Selector must be specified in POST payload"
} Недопустимый объект JSON
Если объект селектора не является правильно сформированным объектом JSON, сообщение об ошибке будет выглядеть примерно так:
{
"error": "bad request",
"reason": "Selector error: expected a JSON object"
} Недопустимый селектор
Если объект селектора не содержит допустимого выражения выбора, сообщение об ошибке будет выглядеть примерно так:
{
"error": "bad request",
"reason": "Selector error: expected a JSON object"
} _design
Фильтр _design пропускает только изменения любых документов проектирования в запрошенной базе данных.
Запрос:
GET /recipes/_changes?filter=_design HTTP/1.1 Accept: application/json Host: localhost:5984
Ответ:
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Type: application/json
Date: Tue, 06 Sep 2016 12:55:12 GMT
ETag: "ARIHFWL3I7PIS0SPVTFU6TLR2"
Server: CouchDB (Erlang OTP)
Transfer-Encoding: chunked
{
"last_seq": "11-g1AAAAIreJyVkEEKwjAQRUOrqCuPoCeQZGIaXdmbaNIk1FLjyrXeRG-iN9Gb1LQRaimFlsAEJnkP_s8RQtM0VGhuz0qTmABfYXdI7h4CgeSiKIosDUVwcotJIpQSOmp_71TIpZty97OgymJAU8G5QrOLVdocrVbdfFzy-wYvcbLVEvrxh5K_NlJggIhSNiCFHbmJbu5yonttMoneYD6kD296eNOzzoRNBNqse2Xyjpd3vP96AcYNTQY4Pt5RdTOuHIwCY5S0qewLwY6OaA",
"pending": 0,
"results": [
{
"changes": [
{
"rev": "10-304cae84fd862832ea9814f02920d4b2"
}
],
"id": "_design/ingredients",
"seq": "8-g1AAAAHxeJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P___7MymBOZcoEC7MmJKSmJqWaYynEakaQAJJPsoaYwgE1JM0o1TjQ3T2HgLM1LSU3LzEtNwa3fAaQ_HkV_kkGyZWqSEXH6E0D666H6GcH6DYyMzIyNTUnwRR4LkGRoAFJAg-ZnJTIQULkAonI_ws0GaWZGqWkmRLkZYsYBiBn3Cdv2AKIS7ENWsG2mxkampsaGmLqyAOYpgEo"
},
{
"changes": [
{
"rev": "123-6f7c1b7c97a9e4f0d22bdf130e8fd817"
}
],
"deleted": true,
"id": "_design/cookbook",
"seq": "9-g1AAAAHxeJzLYWBg4MhgTmHgz8tPSTV0MDQy1zMAQsMcoARTIkOS_P___7MymBOZcoEC7MmJKSmJqWaYynEakaQAJJPsoaYwgE1JM0o1TjQ3T2HgLM1LSU3LzEtNwa3fAaQ_HkV_kkGyZWqSEXH6E0D661F8YWBkZGZsbEqCL_JYgCRDA5ACGjQ_K5GBgMoFEJX7EW42SDMzSk0zIcrNEDMOQMy4T9i2BxCVYB-ygm0zNTYyNTU2xNSVBQDnK4BL"
},
{
"changes": [
{
"rev": "6-5b8a52c22580e922e792047cff3618f3"
}
],
"deleted": true,
"id": "_design/meta",
"seq": "11-g1AAAAIReJyVkE0OgjAQRiegUVceQU9g-mOpruQm2tI2SLCuXOtN9CZ6E70JFmpCCCFCmkyTdt6bfJMDwDQNFcztWWkcY8JXyB2cu49AgFwURZGloQhO7mGSCKWEjtrtnQq5dFXufhaoLIZoKjhXMLtYpc3RatXNxyW_b_ASJVstST_-UPLXRgpESEQpG5DCjlyFm7uc6F6bTKI3iA_Zhzc9vOlZZ0ImItqse2Xyjpd3vDMBfzo_vrPawLiaxihhjOI2lX0BirqHbg"
}
]
} _view
Добавлено в версии 1.2.
Специальный фильтр _view позволяет использовать существующую функцию map в качестве фильтра. Если функция map выдаёт какие-либо данные для обрабатываемого документа, он считается принятым, и событие изменения отправляется в поток. Во многих практических случаях функции filter очень похожи на функции map, поэтому эта возможность помогает сократить объём дублирующегося кода.
Предупреждение
Функции map не обрабатывают документы проектирования, однако использование фильтра _view заставляет их это делать. Убедитесь, что они готовы без ошибок обрабатывать документы с посторонней структурой.
Примечание
Использование фильтра _view не обращается к файлам индекса представления, поэтому обычные параметры запроса представления нельзя использовать для дополнительной фильтрации потока изменений по ключу индекса. Кроме того, CouchDB не возвращает результат мгновенно, как это происходит для представлений: она действительно использует указанную функцию map в качестве фильтра.
Также нельзя сделать такие фильтры динамическими, например обрабатывать параметры запроса или использовать объект контекста пользователя: функция map работает только с документом.
Запрос:
GET /recipes/_changes?filter=_view&view=ingredients/by_recipe HTTP/1.1 Accept: application/json Host: localhost:5984
Ответ:
HTTP/1.1 200 OK
Cache-Control: must-revalidate
Content-Type: application/json
Date: Tue, 06 Sep 2016 12:57:56 GMT
ETag: "ARIHFWL3I7PIS0SPVTFU6TLR2"
Server: CouchDB (Erlang OTP)
Transfer-Encoding: chunked
{
"last_seq": "11-g1AAAAIreJyVkEEKwjAQRUOrqCuPoCeQZGIaXdmbaNIk1FLjyrXeRG-iN9Gb1LQRaimFlsAEJnkP_s8RQtM0VGhuz0qTmABfYXdI7h4CgeSiKIosDUVwcotJIpQSOmp_71TIpZty97OgymJAU8G5QrOLVdocrVbdfFzy-wYvcbLVEvrxh5K_NlJggIhSNiCFHbmJbu5yonttMoneYD6kD296eNOzzoRNBNqse2Xyjpd3vP96AcYNTQY4Pt5RdTOuHIwCY5S0qewLwY6OaA",
"results": [
{
"changes": [
{
"rev": "13-bcb9d6388b60fd1e960d9ec4e8e3f29e"
}
],
"id": "SpaghettiWithMeatballs",
"seq": "11-g1AAAAIReJyVkE0OgjAQRiegUVceQU9g-mOpruQm2tI2SLCuXOtN9CZ6E70JFmpCCCFCmkyTdt6bfJMDwDQNFcztWWkcY8JXyB2cu49AgFwURZGloQhO7mGSCKWEjtrtnQq5dFXufhaoLIZoKjhXMLtYpc3RatXNxyW_b_ASJVstST_-UPLXRgpESEQpG5DCjlyFm7uc6F6bTKI3iA_Zhzc9vOlZZ0ImItqse2Xyjpd3vDMBfzo_vrPawLiaxihhjOI2lX0BirqHbg"
}
]
}
Copyright © 2025 The Apache Software Foundation — Licensed under the Apache License 2.0
https://docs.couchdb.org/en/3.5.1/api/database/changes.html