【问题标题】:How to add fields to each new document created in CouchDB如何向 CouchDB 中创建的每个新文档添加字段
【发布时间】:2015-09-02 00:09:21
【问题描述】:

我知道有几个类似的问题(例如这个问题:CouchDB - trigger code when creating or updating document)涉及 CouchDB 中的“更新处理程序”,但我无法看到它们是如何解决问题的;

  • 每次在我的 CouchDB 数据库中创建一个新文档时,我都想添加一个时间戳
  • 我在 _design/updatehandlers 中创建了一个更新处理程序并验证它被调用:

    "timestampadd" : "function(doc,req) {
    if (!doc) { 
        if ( req.id) { 
            return [{_id : req.id, timestamp : new Date().getTime()}];
        }
        return [null,'added empty'];
    }
    doc.timestamp = new Date().getTime(); 
    return [doc,'added at ' + doc.timestamp];
    }"
    

我的问题是这样的;在数据库中创建新文档时如何使用此功能,即我通常通过对

执行 POST 来创建的新文档
    http://mycouchdb:5984/test_db

我希望 couchdb 在哪里为我创建一个 _id(例如:http://docs.cloudant.com/tutorials/crud/index.html#create)?

如果我按照文档进行操作(在本例中使用 Python),我会发布这样的帖子;

   requests.post("http://mycouchdb:5984/test_db/_design/updatehandlers/_update/timestampadd",headers={'Content-type':'application/json'},data='{"foo":"bar"})

但这里的更新函数 timestampadd 显然采用“doc==null && req.id==null 路径,因为文档尚未创建并且我没有指定 ID。 这使我相信更新功能只能在现有文档上调用,尽管文档似乎暗示了什么,还是我错了?

我可以在现有文档上调用更新并添加时间戳而没有任何麻烦,效果很好,但这里的问题是在创建文档时添加时间戳。

这有可能吗..?

【问题讨论】:

    标签: python couchdb


    【解决方案1】:

    是的,您可以使用更新处理程序来做到这一点。你在正确的轨道上。以下是三种情况:

    创建不指定 id 的文档

    采用的路径是!doc && !req.id。 那是你的例子。与其返回null,不如构建一个新文档并将其返回。您可以使用req.uuid 填充_id。例如:

    return [{_id : req.uuid, timestamp : new Date().getTime()}, 'created new doc'];
    

    创建具有给定 id 的文档

    采用的路径是!doc && req.id。你猜对了。

    更新现有文档

    采用的路径是doc。你猜对了。

    【讨论】:

      【解决方案2】:

      感谢 Simon 为我指明了正确的方向。这是我最终使用的脚本;

      function(doc,req) { 
         if (!doc) { 
             var new_doc = {}; 
             if ( req.id) { 
                 new_doc._id = req.id; 
             } else { 
                  new_doc._id = req.uuid; 
             } 
             new_doc.timestamp = new Date().getTime(); 
             new_doc.body = eval('(' + req.body + ')'); 
             return [new_doc,'added new']; 
         } 
         doc.timestamp = new Date().getTime(); return [doc,'updated'];
       }
      

      请注意,我必须在通过请求传入的正文中添加一个“eval”,以将新文档的内容添加到调用者提供的内容中。

      【讨论】:

      • 这几乎是正确的,但JSON.parse 应该优先于eval。 Eval 效率低下并引入了安全问题。此外,当doc 不是null 时,即在PUT 期间,此代码将忽略对文档的任何更改,而只会更新时间戳。
      猜你喜欢
      • 2011-12-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多