Функция фильтра CouchDB и непрерывная подача - PullRequest
0 голосов
/ 06 сентября 2018

У меня есть функция фильтрации, основанная на свойствах документа, например, «version: A » и работает нормально, пока не произойдет обновление документа в какой-то момент времени, когда это свойство «version: A » будет удалено (или обновлено до «version: * 1005»). * B").

В этот момент я хотел бы получить уведомление о том, что документ обновлен, аналогично тому, когда документ удаляется, но не может найти эффективный способ (без прослушивания и обработки всех изменений документа).

Надеюсь, я что-то упустил, и это не ограничение дизайна.

Ответы [ 3 ]

0 голосов
/ 13 сентября 2018

Самое близкое, к чему вы придете, это использовать представление и отфильтровать ленту изменений на основе этого представления - подробности см. В [1].

Вы можете создать простое представление, включающее «версию» как часть ключа, используя функцию карты, такую ​​как:

function (doc) {
  emit(doc.version, 1);
}

Фид изменений, отфильтрованный этим представлением, уведомит вас о вставке или удалении документов, имеющих поле «версия», а также об изменениях в поле «версия» существующих документов. Однако вы не можете определить предыдущее значение поля «версия» из ленты изменений.

В зависимости от ваших требований вы можете сделать вид более точным. Например, если вы заботитесь только о переходе от формы «A» к «B», то вы можете включить только те документы, которые имеют «A» или «B» в качестве «версии»:

function (doc) {
  if( doc.version === "A" || doc.version === "B") {
    emit(doc.version, 1);
  }
}

Но имейте в виду, что это не вызовет уведомление об изменении при переходе, скажем, с «A» на «C» (или любое другое значение для «версии», в том числе при удалении документа), поскольку уведомления об изменениях отправляются только когда функция карты emit () имеет хотя бы одно значение для документа. Он не уведомляет вас, когда функция карты , используемая для , генерирует хотя бы одно значение для данного документа, но больше не делает!

Вы также можете фильтровать ленту изменений, используя селекторы Mango, поэтому, если запросы Mango работают для вас, возможно, это проще, чем использование представления, но я не уверен, что вы можете получать уведомления об удалениях с помощью селекторов Mango ...

EDIT:

Заявление о простой функции карты, приведенной выше, может быть не совсем правильным, поскольку оно будет уведомлять вас обо всех вставках и удалениях документов, а не только о полях «версия». Вы можете сделать это, чтобы избежать ложных срабатываний:

function (doc) {
  if ( doc.hasOwnProperty( 'version' ) || doc.hasOwnProperty( '_deleted' ) ) {
    emit(doc.version, 1);
  }
}

Это даст уведомления о новых документах с полем «версия» или обновлении, которое добавляет поле «версия» к существующему документу, но все равно будет уведомлять обо всех удалениях.

[1] http://docs.couchdb.org/en/stable/api/database/changes.html#changes-filter-view

0 голосов
/ 19 сентября 2018

В то время как мой другой ответ - верный подход, вчера у меня была такая же ситуация, и я решил посмотреть, как сделать эту работу, используя селекторы Mango. Я сделал следующее:

  1. Создание канала изменений, отфильтрованного селектором запросов (см. Фильтр "_selector" для / db / _changes)
  2. Выполнить запрос (db / _find) и записать результаты
  3. Установить второй канал изменений, который фильтрует только в документах, возвращаемых в (2) (см. Фильтр "_doc_ids" для / db / _changes)

Фид в (1) позволяет узнать, когда новые документы соответствуют вашему запросу, а также изменения в документах, которые соответствуют вашему запросу как до, так и после изменения.

Фид в (2) позволяет узнать, когда было внесено изменение в документ, который ранее соответствовал вашему запросу, независимо от того, соответствует ли оно вашему запросу после того, как изменение было сделано.

Комбинация этих каналов охватывает все случаи, хотя и с некоторыми ложными срабатываниями. При изменении любого из каналов отключите канал изменений в (3) и повторите шаги (2) и (3).

Теперь несколько замечаний по этому подходу:

  • Это действительно подходит только в тех случаях, когда количество документов, возвращаемых запросом, мало, потому что при фильтрации по _id во втором фиде.
  • Необходимо соблюдать осторожность, чтобы убедиться, что второй канал установлен правильно, если есть много изменений, поступающих с первого канала изменений.
  • В некоторых случаях изменения появляются в обоих каналах. Было бы хорошо не реагировать дважды.
  • Если ожидается, что изменения будут происходить часто, тогда примените отмена или ограничение скорости, если вашему клиенту не нужно обрабатывать каждое уведомление об изменении.

Этот подход хорошо работал для меня и дел, с которыми мне приходилось иметь дело.

Ссылки

0 голосов
/ 07 сентября 2018

Поведение, которое вы описали, является правильным.

CouchDB заполняет ленту изменений документами, которые выполняются с помощью функции фильтра. Если вы удалите / измените информацию, которая используется функцией фильтра, отфильтрованный канал изменений будет игнорировать эти обновления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...