我有一个包含一系列嵌入式文档(“评论”)的文档,以及一个如下所示的示例:
{
"_id" : ObjectId("539e9213209e743d107e7202"),
"article" : "article1",
"comments" : [
{
"comment" : "comment1",
"created" : ISODate("2014-06-16T06:43:38Z"),
"_id" : ObjectId("539e921a209e743d107e7203"),
"read" : {
"marked" : false
},
"timesent" : {
"datetime" : "Mon Jun 16 2014 02:43:38 GMT-0400 (EDT)",
"hour" : 2,
"minute" : "43",
"second" : 38,
"am" : true,
"month" : 5,
"day" : 16,
"year" : 2014
}
}
]
}
对于comments数组中的每个注释,有没有办法批量更新字段“read”:{“marked”:true}?
正在使用node.js,并考虑到这样的事情(可疑部分以
开头)if(req.body.readComment){..
// update the article with this id (accessed by PUT at
// http://localhost:4200/api/v1/articles/:article_id)
.put(function(req, res) {
Article.findById(req.params.article_id, function(err, article) {
if (err)
res.send(err);
if (req.body.comment) {
article.comments.push({
comment : req.body.comment,
timesent :
{
datetime : req.body.datetimeNow,
hour : req.body.hourNow,
minute : req.body.minuteNow,
second : req.body.secondNow,
am : req.body.amNow,
month : req.body.monthNow,
day : req.body.dayNow,
year : req.body.yearNow
},
read :
{
marked : req.body.readComment,
datetime : req.body.readCommentDatetime
},
created : req.body.datetimeNow
});
} // if newComment
if (req.body.readComment) {
var comments = // some sort of .find ?
var embeddedDoc;
for (var i=0, length=comments.length; i < length; i++){
embeddedDoc = comments[i];
embeddedDoc_id = // something to find the embedded doc_id ?
console.log(i);
article.comments.push({ // maybe push to the embedded doc_id
read :
{
marked : req.body.readComment,
datetime : req.body.readCommentDatetime
}
});
};
} // if readComment == true (from ajax .put)
// save the article, and check for errors
article.save(function(err) {
if (err)
res.send(err);
res.json({ message: 'Update "' + req.params.article_id });
});
});
})
答案 0 :(得分:2)
因为需要在数组中识别每个注释,所以术语&#34; Bulk&#34;并不真正适用,因为它们本身就是分开的。至于能否只是说&#34;更新所有这些&#39;评论&#39;并将它们标记为true
&#34; ,这不是直接支持的。
但另一方面,您可以使用批量更新操作简化此操作。所以对于一个&#34;列表&#34; &#34;评论&#34;您可以执行以下_id
值:
var bulk = collection.initializeOrderedBulkOp();
comments.forEach(function(commentId) {
bulk.find({ "comments._id": commentId }).updateOne({
"$set": { "comments.$.read.marked": false }
});
counter++;
if ( counter % 500 == 0 ) {
bulk.execute(function(err,result) {
// do something with the result
bulk = collection.initializeOrderedBulkOp();
counter = 0;
});
}
});
// Catch any under or over the 500's
if ( counter > 0 )
bulk.execute(function(err,result) {
// do something with the result here
});
这至少可以避免你通过线路发送更新&#34;每个单独的#34;评论&#34;到服务器实例您发送到API的_id
。通过对结果进行批处理,可以减少流量,减少等待回调响应的时间。
使用&#34; async&#34;你可能更好的这个例子因此,即使循环输入列表也是非阻塞操作。批量大小可能会有所不同,但这只是一个安全的例子,可以保持在16MB BSON硬限制之下,因为整个&#34;请求&#34;等于一个BSON文件。