2016-11-11 61 views
0

我查看了一堆其他的SO帖子,發現了不同的方式來做到這一點,所以我想知道哪個是最受歡迎的。我正在教給學生,所以我想給他們最佳實踐。將新項目推送到mongoDB文檔數組

如果我有以下BlogPost對象(簡體):

var BlogPostSchema = new mongoose.Schema({ 
    body: String, 
    comments: [String] 
}); 

,我想一個新的評論添加到評論的數組這個博客,我能想到的完成至少3種主要途徑這個:

1)將評論推送到Angular中的博客對象,並向/blogs/:blogID端點提交PUT請求,使用包含的新評論更新整個博客對象。

2)提交POST請求到/blogs/:blogID/comments端點在請求體僅僅是新的評論,發現博客,推到在香草JS數組的評論,並保存:

BlogPost.findById(req.params.blogID, function(err, blogPost) { 
    blogPost.comments.push(req.body); 
    blogPost.save(function(err) { 
     if (err) return res.status(500).send(err); 
     res.send(blogPost); 
    }); 
}); 

OR

3)提交POST/blogs/:blogID/comments端點的新評論的請求體,然後使用MongoDB的$push$addToSet的表彰添加註釋的數組:

BlogPost.findByIdAndUpdate(
    req.params.blogID, 
    {$push: {comments: req.body}}, 
    {safe: true, new: true}, 
    function(err, blogPost) { 
     if (err) return res.status(500).send(err); 
     res.send(blogPost); 
    }); 
}); 

我確實發現this stackoverflow post回答者談論選項2和選項3,基本上說,只要你可以使用選項2,這對我來說似乎更簡單。 (而且我通常會盡量避免阻止我使用掛鉤和其他貓鼬產品的方法。)

您怎麼看?有什麼建議?

+0

我會選擇3,兩者和3基本相同。選項3執行findAndUpdate服務器端(導致1次調用返回更新文檔的服務器)。在選項2中,您首先檢索blogPost,然後將更新發送到服務器(.save操作),這是對服務器的兩個調用。 – HoefMeistert

回答

1

從應用角度來看,第3點更好。我認爲的原因是。

  1. 該查詢本身指定了我們試圖實現的內容。它的 容易閱讀。
  2. 保存功能是一張通配符,所以我們不知道它會發生什麼變化。
  3. 如果提取文檔和操縱它,然後調用保存它,有外部,但真正的機會,你可能會搞亂了文檔的一些 等領域操縱 的過程中無意,不點3
  4. 的情況下
  5. 在addToSet的情況下,基本上前一點更明顯。
  6. 想想併發性,如果多個呼叫對同一個博客有不同的評論,並且您正在嘗試選項2,那麼 有可能會覆蓋您在獲取文檔之間以及在您獲取文檔時在 之間完成的更改保存它。選項 3在這個意義上更好。

表現明智,他們都做同樣的事情,所以可能沒有太多或任何明顯的差異。但選項3更安全,更清潔。

+0

我想我唯一擔心的是,如果我需要使用貓鼬的保存前或保存後等鉤子,那麼'findByIdAndUpdate'方法不會讓我這樣做。但是,也許我現在就是這樣寫的,然後如果我發現需要某種前置或後置鉤子,我會將其切換。感謝您的想法! – bobbyz