Уведомление об изменении в CouchDB, когда поле установлено

Я пытаюсь получить уведомления в опросе изменения CouchDB, как только предопределенное поле установлено или изменено. Я уже взглянул на фильтры, которые могут использоваться для фильтрации событий изменения (db/_changes?filter=myfilter). Однако я еще не нашел способ включать эту временную информацию, потому что можно только получить текущую версию документа в этом фильтре функции.

Там возможность состоит в том, чтобы создать такой фильтр?

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

Заранее спасибо!

7
задан b_erb 11 June 2010 в 10:16
поделиться

1 ответ

Вы правы: фильтры и каналы _changes могут видеть только снимки документа. Вам нужна функция, которая может видеть старый документ и новый документ и действовать правильно. Но это недоступно в _filters и _changes .

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

Функции обновления могут получить доступ к обоим документам. Предлагаю вам сделать _обновление функция, которая замечает изменение поля и отмечает это в документе. Далее вы есть простая проверка фильтра для этого флага. Самое приятное то, что вы можете использовать переписать функцию, чтобы HTTP API был точно таким же, как и раньше.

1. Создайте функцию обновления, чтобы отмечать интересные обновления

Ваш _design / myapp будет {"updates", "smart_updater": "(см. Ниже)"} . Функции обновления очень гибкие (см. Мои недавние обработчики обновлений прохождение). Однако мы хотим только имитировать обычный HTTP / JSON API.

Ваши обновления.Поле smart_updater будет выглядеть так:

function (doc, req) {
    var INTERESTING = 'dollars'; // Set me to the interesting field.

    var newDoc = JSON.parse(req.body);
    if(newDoc.hasOwnProperty(INTERESTING)) {
        // dollars was set (which includes 0, false, null, undefined
        // values. You might test for newDoc[INTERESTING] if those
        // values should not trigger this code.
        if((doc === null) || (doc[INTERESTING] !== newDoc[INTERESTING])) {
            // The field changed or created!
            newDoc.i_was_changed = true;
        }
    }

    if(!newDoc._id) {
        // A UUID generator would be better here.
        newDoc._id = req.id || Math.random().toString();
    }

    // Return the same JSON the vanilla Couch API does.
    return [newDoc, {json: {'id': newDoc._id}}];
}

Теперь вы можете ПОСТАВИТЬ или ОТПРАВИТЬ в / db / _design / myapp / _update / [doc_id] , и оно будет выглядеть точно так же, как обычный API, за исключением , если вы обновите поле долларов, он добавит дополнительный флаг , i_was_changed . Вот как вы найдете это изменение потом.

2. Фильтр для документов с измененным полем

Это очень просто:

function(doc, req) {
    return doc.i_was_changed;
}

Теперь вы можете запрашивать канал _changes с параметром ? Filter = . (Репликация также поддерживает этот фильтр, поэтому вы можете перетащить в свою локальную систему все документы который совсем недавно изменил / создал поле.

Это основная идея. Остальные шаги сделают вашу жизнь проще, если вы уже имеют много клиентского кода и не хотят изменять URL-адреса.

3. Используйте переписывание, чтобы HTTP API оставался неизменным

Это доступно в CouchDB 0.11, и лучший ресурс - это сообщение в блоге Яна, красивые URL-адреса в CouchDB .

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

curl -X PUT http://example.com:5984/_config/vhosts/example.com \
  -d '"/db/_design/myapp/_rewrite"'

Затем вы хотите, чтобы поле rewrites в вашем проектном документе, например (не проверено)

[
    {
        "comment": "Updates should go through the update function",
        "method": "PUT",
        "from": "db/*",
        "to"  : "db/_design/myapp/_update/*"
    },
    {
        "comment": "Creates should go through the update function",
        "method": "POST",
        "from": "db/*",
        "to"  : "db/_design/myapp/_update/*"
    },
    {
        "comment": "Everything else is just like normal",
        "from": "*",
        "to"  : "../../../*"
    }
]

(Я снова получил этот код из примеров и существующего кода, который я положил вокруг, но он не отлажен на 100%. Однако я думаю, что это проясняет идею. Также помните, что этот шаг не является обязательным, однако его преимущество в том, что вам никогда не придется измените код клиента.)

6
ответ дан 7 December 2019 в 09:56
поделиться
Другие вопросы по тегам:

Похожие вопросы: