couchdb/cloudant 更新处理程序未按预期工作

Posted

技术标签:

【中文标题】couchdb/cloudant 更新处理程序未按预期工作【英文标题】:couchdb/cloudant update handler not working as expected 【发布时间】:2016-02-25 14:32:10 【问题描述】:

我正在开发一个使用 Cloudant 作为数据库的应用程序。我有一种情况,我几乎同时对同一个文档进行了两次数据库调用,但是,正因为如此,我得到了一个冲突错误。所以我尝试在 cloudant 数据库中创建一个更新处理函数,如下所示:


  "_id": "_design/_updateHandler",
  "updates": 
    "in-place": "function(doc, req) 
        var field = req.body.field,
        var value= req.body.value,
        var doc[field] = value;
        return [doc, toJSON(doc)];
    "
  

它会在文档中添加一个字段,但不会更新它的现有字段。这是预期的行为吗?在cloudant documentation for update handlers 和couchdb documentation 中看起来都不是这样。

如果没有,我该如何解决这个问题,以便更新现有字段? 另外,正如this question 中所回答的那样,更新处理函数仍然会发生更新冲突,但我该如何避免呢?

提前致谢:)

【问题讨论】:

我建议你给你一个咨询锁机制;或重试冲突。用于咨询锁;您可以简单地使用 memcache/redis;或在记忆字典中;或 cloudant 中的锁定文档。用于重试冲突方法;只需在冲突错误 (http 409) 上重新应用您的更改。 您粘贴的示例代码有很多错误... var 语句后的逗号,var doc 当 doc 已经定义时,等等 :( 你有更新的代码吗?或者更接近你的代码'正在尝试?您可以在浏览器控制台中自行测试该功能,以首先清理 JS。 此外,CouchDB Docs 中的示例比 wiki 中的示例更容易迭代:docs.couchdb.org/en/1.6.1/couchapp/ddocs.html#update-functions 【参考方案1】:

这是一个 CouchDB 和 Cloudant 兼容的更新函数的工作示例,用于执行您所追求的操作——更新单个字段。

function(doc, req) 
  if (!doc) doc = _id: req.uuid;
  var body = JSON.parse(req.body);
  var field = body.field;
  var value = body.value;
  doc[field] = value;
  return [doc, JSON.stringify(doc)];

POST 请求的主体被认为是有效的 JSON,因此您可能需要对 application/json 进行一些标头检查。

此外,如果您只打算像这里那样做 field = value 的东西,那么application/x-www-form-url-encoded 会更好,因为它会降低您的有效负载大小和解析时间——CouchDB 和 Cloudant 会自动将该媒体类型解析为req.form 对象。

最后,最好不要在您提供给 CouchDB 或 Cloudant 的任何内容前加上下划线,因为它被认为是***字段开头的保留字符和 _id 值。 _design/_updateHandler 的名字(随后)非常令人困惑......

这里是 JSON 复制/粘贴到您的数据库中以获得有效的更新功能来做你想做的事:


    "_id": "_design/overwrite",
    "updates": 
        "in-place": "function(doc, req) \n  if (!doc) doc = _id: req.uuid;\n  var body = JSON.parse(req.body);\n  var field = body.field;\n  var value = body.value;\n  doc[field] = value;\n  doc.body = body;\n  return [doc, JSON.stringify(doc)];\n"
    

要更新现有文档,您需要发出这样的 HTTP 请求(其中 bigbluehat 是先前存储的文档的 _id:

POST /db/_design/overwrite/_update/in-place/bigbluehat
Content-Type: application/json

"field": "name", "value": "BigBlueHat"

或者,如果您没有在请求 URL 中包含文档 _id,您将获得一个使用 req.uuid 值来存储新文档的新文档。

希望有帮助!

【讨论】:

感谢您指出代码错误!我因为冲突而感到沮丧,最终得到了这段代码,但什么也没发生。我仍然对解决冲突的最佳方法有疑问。现在我正在使用 Safak Ulusoy 的解决方案,但感觉不对。有没有更好的解决方法? 忘了提...还有非常有用的提示! 冲突不一定是坏事。 :) 这仅取决于它们发生的原因,您是否可以围绕(或为!)它们进行架构,以及它的根本原因是什么 - 对单个文档的过度频繁更新实际上应该存储在多个文档中? (错误)将 CouchDB 用于 Redis 更擅长的事情(内存计数)?等等。也许发布另一个问题并ping我。 ^_^

以上是关于couchdb/cloudant 更新处理程序未按预期工作的主要内容,如果未能解决你的问题,请参考以下文章

身份服务器 4 中的静默令牌更新,js 客户端应用程序未按预期工作

sqlCommandBuilder 更新未按预期工作

MySQL ResultSet 可滚动/可更新未按预期工作

Angular 自定义指令范围未按预期更新

通知操作后台任务未按预期运行

Cordova iOS - inAppBrowser 未按预期工作