我想知道如何使用更新功能在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."]
}
}
感谢您的帮助,
答案 0 :(得分: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的正文数据。上面的示例函数要求客户端以application/x-www-form-urlencoded
格式发送带有至少两个参数的HTTP POST:name
和data
(如果提供,将使用content_type
参数) :
name=logo.png&content_type=image/png&data=iVBORw0KGgoA...
测试更新功能:
查找一个小图片并对其进行base64编码:
$ base64 logo.png | sed 's/+/%2b/g' > post.txt
sed
脚本对+
个字符进行编码,因此无法转换为空格。
post.txt
并将name=logo.png&content_type=image/png&data=
添加到文档顶部。使用curl以post.txt文件作为正文调用更新函数,替换为刚刚创建的文档的ID。
curl -X POST -d @post.txt http://127.0.0.1:5984/mydb/_design/myddoc/_update/upload/193ecff8618678f96d83770cea002910
这是在OSX上运行的CouchDB 1.6.1上测试的。
更新:@janl非常友好地提供了有关此答案导致性能和扩展问题的原因的一些详细信息。通过上传处理程序上传附件有两个主要问题:
fork()
个couchjs
进程来处理上传。即使couchjs
进程已在运行,服务器也必须通过stdin将整个HTTP请求流式传输到外部进程。对于大型附件,请求的传输可能需要大量时间和系统资源。对于像这样的更新函数的每个并发请求,CouchDB将不得不分叉一个新的couchjs
进程。由于下面将要解释的原因,进程运行时间会相当长,因此您可以轻松地耗尽RAM,CPU或处理更多并发请求的能力。_attachments
属性并流回CouchDB服务器(!)之后,服务器必须解析响应JSON,解码base64编码的附件主体,并将二进制主体写入磁盘。向文档添加附件的标准方法 - PUT /db/docid/attachmentname
- 将二进制请求主体直接流式传输到磁盘,不需要两个处理步骤。上述功能可以使用,但在高度可扩展的系统中使用它之前需要考虑一些非常重要的问题。