Spec-Zone.ru › CouchDB 3.5

/{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

  • Content-Type –

    • 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

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API