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

相关问题