Я пытаюсь получить уведомления в опросе изменения CouchDB, как только предопределенное поле установлено или изменено. Я уже взглянул на фильтры, которые могут использоваться для фильтрации событий изменения (db/_changes?filter=myfilter
). Однако я еще не нашел способ включать эту временную информацию, потому что можно только получить текущую версию документа в этом фильтре функции.
Там возможность состоит в том, чтобы создать такой фильтр?
Если это не работает, я мог бы экспортировать свое поле в отдельную базу данных и единственный опрос для изменений в том дб, но я предпочту держать свои данные вместе по очевидным причинам.
Заранее спасибо!
Вы правы: фильтры и каналы _changes
могут видеть только снимки документа. Вам нужна функция, которая может видеть старый документ и новый документ и действовать правильно. Но это недоступно в _filters
и _changes
.
Очевидно, ваш клиентский код знает, обновляет ли он это поле. Вы можете обновить свой клиентский код, но есть лучшее решение.
Функции обновления могут получить доступ к обоим документам. Предлагаю вам сделать _обновление функция, которая замечает изменение поля и отмечает это в документе. Далее вы есть простая проверка фильтра для этого флага. Самое приятное то, что вы можете использовать переписать функцию, чтобы HTTP API был точно таким же, как и раньше.
Ваш _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
. Вот как вы найдете это изменение
потом.
Это очень просто:
function(doc, req) {
return doc.i_was_changed;
}
Теперь вы можете запрашивать канал _changes
с параметром ? Filter =
. (Репликация
также поддерживает этот фильтр, поэтому вы можете перетащить в свою локальную систему все документы
который совсем недавно изменил / создал поле.
Это основная идея. Остальные шаги сделают вашу жизнь проще, если вы уже имеют много клиентского кода и не хотят изменять URL-адреса.
Это доступно в 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%. Однако я думаю, что это проясняет идею. Также помните, что этот шаг не является обязательным, однако его преимущество в том, что вам никогда не придется измените код клиента.)