1

假设我有一个基本的博客 Web 应用程序,它使用以下文档架构来写博客文章。

{
    _id: ObjectId(...),
    title: "Blog Post #1",
    text: "<p>This is my blog post!</p>",
    comments: [
        {
            user: "username1",
            time: Date(...),
            text: "This is a great blog post!"
        },
        {
            user: "username2",
            time: Date(...),
            text: "This is even better than sliced bread!"
        }
    ]
}

这一切都很好,但现在让我们假设用户可以编辑或删除他的评论。最重要的是,它是一个网络应用程序,因此可能有多个人同时编辑或删除他们的评论。现在假设我以“username2”身份登录并尝试编辑我的评论,这是评论数组中的第二个项目 - 索引位置 1。就在我单击“保存”之前,user1 登录并删除他的第一个评论数组中的项。如果我的代码尝试按索引位置删除用户 2 的评论,它将失败,因为数组中不再有 2 个项目。

我想到了两个想法,但我对任何一个都不疯狂。

  • 在每条评论上创建某种 id
  • 在父文档上创建一个“lastModified”时间戳,并且仅在文档没有任何更改时才保存编辑。

处理这种情况的最佳方法是什么?如果我真的需要每个评论的 id,我必须自己生成它吗?它应该是什么数据类型?还是最好同时使用我的两个想法?还是我什至没有考虑过其他选择?

4

1 回答 1

2

在我看来,拥有不同的作者是嵌入文档的主要缺点。您可能想看看这个提供不同解决方案的讨论。我会尽量避免对一个文档使用不同的作者,Comments而是使用单独的集合,其中每条评论都归其作者所有。postId您可以通过索引字段相当快地获取帖子的所有评论。然后评论只是有一个常规_id字段。使用 an 是有意义的,ObjectId因为它会自动存储评论的创建时间,并且默认情况下它是一个单调索引。

在父文档上创建一个“lastModified”时间戳,并且仅在文档没有任何更改时才保存编辑。

这被称为“乐观锁定”,如果并发操作的概率很高,通常情况下并不好。在博客文章的情况下,新文章收到的评论可能比旧文章多得多,所以我想说碰撞概率有点高。

还有另一个令人讨厌的副作用:假设博客文章作者想要修改文本,但同时有人添加或删除了评论。现在即使是博客作者也无法更改文本,除非您对文本使用原子$set操作并绕过版本检查。

于 2013-06-05T09:09:46.503 回答