将新项目推送到 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 文档数组的主要内容,如果未能解决你的问题,请参考以下文章

通过 mongoose 将项目推送到 mongo 数组中

通过 mongoose 将项目推送到 mongo 数组中

通过 mongoose 将项目推送到 mongo 数组中

通过 mongoose 将项目推送到 mongo 数组中

通过 mongoose 将项目推送到 mongo 数组中

通过 mongoose 将项目推送到 mongo 数组中