2014-09-26 60 views
2

我想知道如何使用更新功能上传附件在CouchDB中。如何使用更新功能上传附件在CouchDB中

在这里,你会发现我的更新功能的示例添加文档:

function(doc, req){ 
if (!doc) { 
    if (!req.form._id) { 
     req.form._id = req.uuid; 
    } 
    req.form['|edited_by'] = req.userCtx.name 
    req.form['|edited_on'] = new Date(); 

    return [req.form, JSON.stringify(req.form)]; 
} 
else { 
    return [null, "Use POST to add a document."] 
} 

}用于删除文件

例如:

function(doc, req){ 
if (doc) { 
    for (var i in req.form) { 
     doc[i] = req.form[i]; 
    } 

    doc['|edited_by'] = req.userCtx.name 
    doc['|edited_on'] = new Date(); 
    doc._deleted = true; 

    return [doc, JSON.stringify(doc)];  
} 
else { 
    return [null, "Document does not exist."] 
} 

}

感谢您帮助,

回答

2

通过修改文档的_attachments属性,可以使用更新功能将附件添加到文档。这里有一个更新的功能,这将附件添加到现有文档的例子:

function (doc, req) { 
    // skipping the create document case for simplicity 
    if (!doc) { 
    return [null, "update only"]; 
    } 

    // ensure that the required form parameters are present 
    if (!req.form || !req.form.name || !req.form.data) { 
    return [null, "missing required post fields"]; 
    } 

    // if there isn't an _attachments property on the doc already, create one 
    if (!doc._attachments) { 
    doc._attachments = {}; 
    } 

    // create the attachment using the form data POSTed by the client 
    doc._attachments[req.form.name] = { 
    content_type: req.form.content_type || 'application/octet-stream', 
    data: req.form.data 
    }; 

    return [doc, "saved attachment"]; 
} 

对于每一个附件,你需要一个名称,内容类型,按Base64编码的身体数据。上面的例子中功能要求客户端发送的HTTP POST在application/x-www-form-urlencoded格式与至少两个参数:namedata(如果提供的一个content_type参数将被使用):

name=logo.png&content_type=image/png&data=iVBORw0KGgoA... 

要测试更新功能:

  1. 找到一个小图像,并进行Base64编码它:

    $ base64 logo.png | sed 's/+/%2b/g' > post.txt 
    

    sed脚本编码+个字符,因此它们不会转换为空格。

  2. 编辑post.txt并将name=logo.png&content_type=image/png&data=添加到文档的顶部。
  3. 使用Futon在CouchDB中创建一个新文档。
  4. 使用curl以post.txt文件为主体调用update函数,替换您刚刚创建的文档的ID。

    curl -X POST -d @post.txt http://127.0.0.1:5984/mydb/_design/myddoc/_update/upload/193ecff8618678f96d83770cea002910 
    

这是对CouchDB的1.6.1测试OSX上运行。


更新:@janl还跟提供关于为什么这个答案可能会导致性能和扩展性问题的一些细节。通过上传处理​​上传附件主要有两个问题:

  1. 处理程序用JavaScript编写的,所以CouchDB的服务器必须fork()一个couchjs进程来处理上传上传。即使couchjs进程已在运行,服务器也必须通过stdin将整个HTTP请求流式传输到外部进程。对于大型附件,请求的传输可能花费大量时间和系统资源。对于像这样的更新函数的每个并发请求,CouchDB将不得不分叉一个新的couchjs进程。由于接下来要解释的流程运行时间会相当长,因此您可以轻松地耗尽RAM,CPU或处理更多并发请求的能力。
  2. _attachments属性由上传处理程序填充并流式传输回CouchDB服务器(!)后,服务器必须解析响应JSON,解码base64编码的附件体并将二进制体写入磁盘。将附件添加到文档的标准方法 - PUT /db/docid/attachmentname - 将二进制请求主体直接传输到磁盘,并且不需要两个处理步骤。

上述功能可以正常工作,但在高度可扩展的系统中使用它之前,需要考虑一些不平凡的问题。

+0

Thanks!, 现在我使用的方法:“PUT/db/doicd/attachmentname”。 问题是,每个人都可以上传文件,而无需在couchDB中进行身份验证;出于安全原因,我想使用CouchApp中的“更新”功能,而不是直接在数据库中使用。 你有我的问题的另一种解决方案,或者我有我的数据库有问题。 – jfergt 2014-10-02 23:32:47