2

假设我有一个带有嵌入式作者的帖子文档。

{
    name: "some post",
    text: "some text",
    author:{
        avatar_img: "http://www.someimage.com/1"
    },
    comments: [
        {
            user: "some name"
            avatar_img: "http://www.someimage.com/5"
        }
    ]
}

现在假设我在前端使用这些数据并在页面上显示带有作者图像的帖子。当作者更改他的头像 url 时会发生什么?我将不得不使用新的图片网址更新每篇文章。这是正确的方法吗?我看到的唯一选择是引用“用户”文档,但是每个帖子都会有 2 个数据库请求。更不用说所有的评论也需要 2 db 请求来获取图像 url....

4

1 回答 1

0

在系统设计层面有两种方法 - 当有人更改他们的头像时,您应该让他们之前发布的帖子显示旧头像还是新头像?

有些人可能会声称,如果您在发布时拥有头像 [X],那么返回该帖子应该“永远”显示相同的头像图像。其他人可能认为作者的头像是他们的标识符,应该更改它以匹配他们当前的头像 [Y]。

如果你想做前者,你已经完成了:)

如果您想做后者,那么当作者将他们的头像从 [X] 更改为 [Y] 时,您可以运行单个更新,如下所示:

db.posts.update({ "author.name":"joejoe", "author.avatar_img":"[X]"}, 
                { $set:{"author.avatar_img":"[Y]"}},
                { multi : true }
               );

我在这里做了一些假设-一个是您存储作者的姓名而不仅仅是avatar_img,另一个是每个帖子只能有一个作者,第三是您的多次更新可能会被中断,这就是我匹配条件的原因既是作者姓名,也是他们的旧头像。

这照顾作者。现在,评论呢?我要告诉你,将评论嵌入到帖子文档中是一个“坏主意(tm)”——出于性能原因,您希望限制文档的持续增长,因此您最多可以将前几条评论嵌入到文档本身中(这样您可以在显示帖子时显示前几条评论)但评论属于他们自己的集合,如果查看者要求查看更多评论,您可以在其中查询它们。一旦它们位于单独的集合中,您就可以对它进行与对帖子所做的相同的更新(如果您愿意的话)。由于您将帖子中的数组元素数量限制为少数评论,因此您可以使用另一个(或几个)更新命令轻松更新这些评论。

请注意,当用户更改头像时,以非规范化形式更新头像将是异步的,但这没关系,因为用户不会经常更改头像,您不在乎更新是否需要更长的时间,但您将获得巨大的性能优势通过优化最频繁的操作 - 将帖子显示到只有一次阅读的视图中。

于 2013-05-05T17:18:26.823 回答