Javascript Mongoose-循环一个嵌入文档的数组。将新值整体推送到一个字段?

Javascript Mongoose-循环一个嵌入文档的数组。将新值整体推送到一个字段?,javascript,node.js,mongodb,mongoose,mongodb-query,Javascript,Node.js,Mongodb,Mongoose,Mongodb Query,我有一个带有嵌入文档数组(“注释”)的文档,示例如下: { "_id" : ObjectId("539e9213209e743d107e7202"), "article" : "article1", "comments" : [ { "comment" : "comment1", "created" : ISODate("2014-06-16T06:43:38Z"), "_id" :

我有一个带有嵌入文档数组(“注释”)的文档,示例如下:

{
    "_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
            }
        }
    ]
}
对于注释数组中的每个注释,是否有方法批量更新字段“read”:{“marked”:true}

我正在使用node.js,并且有类似的想法(有问题的部分以

如果(req.body.readComment){

//使用此id更新文章(由PUT访问)
// http://localhost:4200/api/v1/articles/:article_id)
.put(功能(请求、恢复){
Article.findById(req.params.Article_id,函数(err,Article){
如果(错误)
res.send(err);
if(请求正文注释){
article.comments.push({
注释:req.body.comment,
时间:
{
datetime:req.body.datetimeNow,
小时:req.body.hourNow,
分钟:请求正文分钟,
第二个:req.body.secondNow,
am:req.body.amNow,
月份:req.body.monthNow,
日期:req.body.dayNow,
年份:req.body.EARNOW
},
阅读:
{
标记:req.body.readComment,
datetime:req.body.readCommentDatetime
},
已创建:req.body.datetimeNow
});
}//如果新来者
if(请求正文readComment){
var comments=//某种类型的.find?
var嵌入doc;
for(var i=0,length=comments.length;i
由于每个注释都需要在数组中进行标识,“批量”一词实际上并不适用,因为它们本质上是分开的。至于能够说“更新所有这些‘注释’并将它们标记为
真的
”,这是不直接支持的

但另一方面,您可以通过批量更新操作简化此操作。因此,对于“注释”
\u 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
    });
这至少可以避免为发送到API中的每个“注释”
\u id
向服务器实例发送“在线”更新。通过成批处理结果,可以减少通信量,减少回调中等待响应的时间


使用“async”可能会更好,因此即使循环输入列表也是一种非阻塞操作。批大小可能会有所不同,但这只是一个安全的示例,可以保持在16MB BSON硬限制下,作为整个“请求”"相当于一个BSON文档。

非常酷。谢谢。关于获取文章文档中每条评论的commentId,有什么建议吗?还是我应该从前端的隐藏字段中获取每条评论的commentId,通过ajax发送?@Stack这取决于您在客户端中填充数据的方式。如果您只是给HTML添加一个隐藏字段似乎是合理的。如果您通过JSON响应中的数据进行渲染,那么应该有一种方法来获取相关值。这实际上是另一个问题,取决于您的实现。答案中是否有不符合您问题需要的内容?@NeilLunn不一定..数据库h由于你的回答有点改变(感谢你的精彩),我还没有来得及抓住这些评论。_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
    });