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

b_e*_*erb 7 couchdb

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

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

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

提前致谢!

Jas*_*ith 6

你是对的:过滤器和_changes源只能看到文档的快照.您需要的是一个可以查看旧文档和新文档并正确操作的函数.但这在_filters和中是不可用的_changes.

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

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

1.创建更新功能以标记有趣的更新

_design/myapp会的{"updates", "smart_updater": "(see below)"}.更新功能非常灵活(请参阅我最近的更新处理程序 演练).但是我们只想模仿普通的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}}];
}
Run Code Online (Sandbox Code Playgroud)

现在你可以PUT或POST到/db/_design/myapp/_update/[doc_id]它,它会感觉就像普通的API,除非你更新美元字段,它会添加一个额外的标志,i_was_changed.这就是你以后会发现这种变化的方式.

2.过滤包含已更改字段的文档

这非常简单:

function(doc, req) {
    return doc.i_was_changed;
}
Run Code Online (Sandbox Code Playgroud)

现在,您可以_changes使用?filter=参数查询Feed .(复制也支持此过滤器,因此您可以将最近更改/创建该字段的所有文档提取到本地系统.

这是基本的想法.如果您已经拥有大量客户端代码并且不想更改URL,那么剩下的步骤将使您的生活更轻松.

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

这在CouchDB 0.11中可用,最好的资源是Jan的博客文章, CouchDB中很好的URL.

简而言之,您需要一个vhost,它将所有流量发送到您的重写器(它本身是基于URL的所有设计doc功能的灵活"保镖").

curl -X PUT http://example.com:5984/_config/vhosts/example.com \
  -d '"/db/_design/myapp/_rewrite"'
Run Code Online (Sandbox Code Playgroud)

那么你想要一个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"  : "../../../*"
    }
]
Run Code Online (Sandbox Code Playgroud)

(再一次,我从示例和现有代码中得到了这些代码,但它并没有100%调试.但是我觉得这个想法非常明确.还记得这一步是可选的,但优点是,你永远不必改变你的客户代码.)