【问题标题】:CouchDB auto-generated fieldsCouchDB 自动生成的字段
【发布时间】:2012-11-11 13:24:56
【问题描述】:

我的文档中有 ctime 和 mtime(创建/修改时间)字段。

如何让 couchDB 为我处理这些?例如:

// Create a dog
curl -X POST http://localhost:5984/dogs -d '{"name": "Bill"}'
{"ok":true,"id":"75efaeb93aa2ed75ffa0abf9f5006d40","rev":"1-49ce25e3db701c8cb613c1fd18d99619"}

-> ctime 和 mtime 应该是自动生成的

// Update a dog
curl -X PUT http://localhost:5984/dogs/75efaeb93aa2ed75ffa0abf9f5006d40?rev=1-49ce25e3db701c8cb613c1fd18d99619 -d '{"name": "BILL"}'

-> mtime 应该会自动更新


我正在使用validate_doc_update 来处理这个问题,比如:

function (newDoc, oldDoc, userCtx) {
  //
  // sanity checks
  //

  if (oldDoc && newDoc.ctime) throw {"forbidden": "ctime cannot be changed!"}

  ...

  //
  // Auto-generate fields
  //

  var now = new Date().toISOString();

  // mtime
  newDoc.mtime = now;

  // ctime
  if (!oldDoc) newDoc.ctime = now;
}

但没有运气:更改 newDoc 似乎没有效果(通过副本?)

谢谢

【问题讨论】:

标签: couchdb


【解决方案1】:

不,您不能在validate_doc_update 函数中修改文档内容。如果您使用Document API 或通过充当服务器端处理程序的update handlers,则需要在客户端上设置此值。在validate_doc_update 函数中,您只能验证此值并接受/拒绝文档的新版本。

由于时间戳不易控制,并且客户端可以通过“不正确”(非实际)值传递您的更新处理程序很容易,我看到的唯一解决方案是在当前时间戳的特定范围内验证 mtime(+/- 2- 3 秒是可以的范围)并且需要 ctime 字段作为初始文档版本。

但是这个验证是错误的,因为你会破坏复制:复制的文档将具有过去的 ctime 和 mtime 字段,并且在这种情况下验证函数将拒绝它。

【讨论】:

  • 1.好的,我知道我无法“编辑”validate_doc_update 中的文档。 2.关于复制和验证时间的有趣的东西:没有想过这个问题。结论:什么结论? :) 简单的方法是信任客户端并且不验证[cm]time。另一方面,更新处理程序需要额外的 HTTP 请求,只是为了创建这些字段:这并不理想......
  • 结论很简单:创建文档时需要ctime,但不允许他以后修改。 mtime 修改是允许的,但新值应该大于当前值并且仍然小于 now (确保您已处理 UTC)。关于复制只需做出决定:old mtime 的文档是否可以覆盖 new 的文档。如果可以 - 为那些可以覆盖此类值的规则制定规则(通过文档作者、特殊角色等)。
  • 永远不要相信用户数据(:除非它经过你的验证。所以对于客户来说,一切都很简单:他们将保持他们的逻辑与你的逻辑保持同步,或者他们将使用你的更新处理程序。在某些时候维护人员会厌倦一次又一次地修复文档存储,他们会高兴地切换到您的更新处理程序。当然,仍然有一些窗口可以打破这种逻辑,但一切都取决于这些字段对您有多少价值,您是否可以允许一些对他们来说是错误的?至于我,我现在遵循相同的策略,没有任何严重的问题。
猜你喜欢
  • 2011-07-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-07-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多