设置字段时更改CouchDB中的通知

时间:2010-06-11 10:16:30

标签: couchdb

一旦设置或更改了预定义字段,我就会尝试在CouchDB更改轮询中收到通知。我已经看过可用于过滤更改事件的过滤器(db/_changes?filter=myfilter)。但是,我还没有找到包含此时态信息的方法,因为您只能在此过滤器函数中获取文档的当前版本。

是否有可能创建这样的过滤器?

如果它不起作用,我可以将我的字段导出到一个单独的数据库,并且只对该数据库中的更改进行轮询,但我更愿意将这些数据保存在一起,原因很明显。

提前致谢!

1 个答案:

答案 0 :(得分:6)

您是对的:过滤器和_changes Feed只能查看文档的快照。您需要的是一个可以查看旧文档和新文档并正确操作的函数。但是在_filters_changes中无法使用。

显然,您的客户端代码知道它是否更新该字段。您可以更新客户端代码,但有更好的解决方案。

更新功能可以访问这两个文档。我建议你创建一个_update 注意到字段更改并标记文档中的字符的函数。接下来你 有一个简单的过滤器检查该标志。最好的部分是,你可以使用 重写函数使HTTP API与以前完全相同。

1。创建更新函数以标记有趣的更新

您的_design/myapp将是{"updates", "smart_updater": "(see below)"}。 更新功能非常灵活(请参阅我最近的update handlers 演练)。但是我们只想模仿普通的HTTP / JSON API。

您的updates.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}}];
}

现在你可以PUT或POST到/db/_design/myapp/_update/[doc_id],它会感觉到 就像普通的API,除了,如果你更新美元字段,它将添加 附加标志i_was_changed。这就是你将如何找到这种变化 后面。

2。过滤具有更改字段的文档

这非常简单:

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

现在,您可以使用_changes参数查询?filter= Feed。 (复制 还支持此过滤器,因此您可以将所有文档提取到本地系统 最近改变/创造了这个领域。

这是基本的想法。剩下的步骤将使您的生活更轻松 已经有很多客户端代码,不想更改URL。

3。使用重写来保持HTTP API相同

这可以在CouchDB 0.11中找到,最好的资源是Jan的博文, nice URLs in CouchDB

简单地说,您需要一个将所有流量发送到您的重写器的虚拟主机(它本身 是基于URL的所有设计doc功能的灵活“保镖”。

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%调试。但是我觉得这个想法很清楚。 还记得这一步是可选的,但优点是,你永远不必 更改您的客户端代码。)