将新项目推送到 mongoDB 文档数组

Posted

技术标签:

【中文标题】将新项目推送到 mongoDB 文档数组【英文标题】:Pushing new item to a mongoDB document array 【发布时间】:2017-03-26 05:04:45 【问题描述】:

我查看了一堆其他 SO 帖子,并找到了不同的方法来做到这一点,所以我想知道哪个是最首选的。我正在教学生这个,所以我想给他们最佳实践。

如果我有以下BlogPost 对象(简体):

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

我想为这个博客的 cmets 数组添加一条新评论,我可以想到至少 3 种主要方法来实现这一点:

1) 将评论推送到 Angular 中的博客对象,并向 /blogs/:blogID 端点提交 PUT 请求,使用包含的新评论更新整个博客对象。

2) 向/blogs/:blogID/comments 端点提交POST 请求,其中请求正文只是新评论,找到博客,将评论推送到vanilla 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);
    );
);

3) 将 POST 提交到带有新评论请求正文的 /blogs/:blogID/comments 端点,然后使用 MongoDB 的 $push$addToSet 将推荐添加到 cmets 数组中:

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 *** post,其中回答者谈到了选项 2 与选项 3,并且基本上说尽可能使用选项 2,这对我来说似乎更简单。 (而且我通常会尽量避免使用钩子和其他猫鼬好东西的方法。)

你怎么看?有什么建议吗?

【问题讨论】:

我会选择选项 3。2 和 3 基本相同。选项 3 执行 findAndUpdate 服务器端(导致 1 次调用返回更新文档的服务器)。在选项 2 中,您首先检索 blogPost,然后将更新发送到服务器(.save 操作),这是对服务器的 2 次调用。 【参考方案1】:

从应用的角度来看,第 3 点更好。我认为的原因是。

    查询本身指定了我们要达到的目标。它是 易于阅读。 save 函数是一个通配符,所以我们不知道它会改变什么。 如果您获取文档并对其进行操作,然后调用保存它,那么您可能会搞砸一些外部但真实的机会 正在处理的文档的其他字段 无意中,不是第 3 点的情况。 在 addToSet 的情况下,基本上上一点更明显。 考虑并发性,如果多个调用对同一个博客有不同的评论并且您正在尝试选项 2,那么 您可能会覆盖所做的更改 在您获取文档和保存文档之间。选项 从这个意义上说,3 更好。

在性能方面,它们都做同样的事情,因此可能没有太大或任何明显的差异。但选项 3 更安全、更清洁。

【讨论】:

我想我唯一关心的是,如果我需要使用 mongoose 的 pre-save 或 post-save 等钩子,那么 findByIdAndUpdate 方法不会让我这样做。但也许我现在是这样写的,然后如果我发现需要某种前钩子或后钩子,我会切换它。感谢您的想法!

以上是关于将新项目推送到 mongoDB 文档数组的主要内容,如果未能解决你的问题,请参考以下文章