2014-06-16 26 views
0

我有嵌入文檔(「註釋」)的陣列的文檔,並且看起來像這樣的一個示例:Mongoose - 將嵌入式文檔的數組循環以便向字段集中新的值。

{ 
    "_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){..開始

// 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

有沒有答案,不符合你的問題的需要? –

+0

@NeilLunn不一定..數據庫已經發生了一些變化(感謝你的真棒答案),並且還沒有想辦法抓住comments._id,因此還沒有對此進行測試。與往常一樣,答案看起來很理想,所以接受,還是應該先測試它?剛剛投票! – StackThis

回答

2

好,因爲每個評論都需要在陣列中進行識別,「Bulk」一詞並不適用,因爲它們本質上是分開的。至於能夠說「更新所有這些'評論'並將它們標記爲true,這不是直接支持。

但另一方面,您可以使用批量更新操作簡化此操作。因此,對於一個的「註釋」 _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 
    }); 

這至少避免了您在發送「通過線路」服務器實例的每一個「註釋」 _id您發送更新進入API。通過對結果進行批處理,可以減少流量,並縮短等待回調中的響應時間。

你可能更喜歡「async」這個例子,所以即使循環輸入列表也是非阻塞操作。批量大小可能會有所不同,但這僅僅是一個安全示例,可以保持在16MB BSON硬限制下,因爲整個「請求」等於一個BSON文檔。

+0

非常酷。謝謝你。有關在文章文檔中獲取每條評論評論標準的建議?還是應該從前端的隱藏字段中抓取每條評論的commentId,以便通過ajax發送? – StackThis

+0

@StackThis取決於您如何在客戶端真正填充數據。如果你只是渲染HTML,那麼隱藏的領域似乎是合理的。如果您通過來自JSON響應的數據進行渲染,那麼應該有一種方法來獲取關聯的值。真的是另一個問題,實際上取決於你的實施。 –

相關問題