Python MongoDB:将用户嵌入到评论中

Python MongoDB:将用户嵌入到评论中,python,mongodb,mongoalchemy,nosql,Python,Mongodb,Mongoalchemy,Nosql,对于非常简单的问题(或不是非常简单的问题),我找不到“最佳”解决方案 拥有一组经典的数据:附加到用户的帖子、附加到帖子和用户的评论 现在我无法决定如何构建scheme/类 一种方法是将用户id存储在评论和内部。 但当我在页面上有200条评论时会发生什么呢? 或者当我在页面上有N篇帖子时? 我的意思是应该有200个额外的数据库请求来显示用户信息(比如姓名、头像) 另一个解决方案是将用户数据嵌入到每条评论和每条帖子中 但第一->这是巨大的开销,第二->模型系统正在被破坏(使用mongoalchemy

对于非常简单的问题(或不是非常简单的问题),我找不到“最佳”解决方案

拥有一组经典的数据:附加到用户的帖子、附加到帖子和用户的评论

现在我无法决定如何构建scheme/类

一种方法是将用户id存储在评论和内部。
但当我在页面上有200条评论时会发生什么呢?
或者当我在页面上有N篇帖子时?
我的意思是应该有200个额外的数据库请求来显示用户信息(比如姓名、头像)

另一个解决方案是将用户数据嵌入到每条评论和每条帖子中

但第一->这是巨大的开销,第二->模型系统正在被破坏(使用mongoalchemy),第三->用户可以更改他的信息(比如化身)。然后呢?据我所知,对大量评论或帖子的更新操作并不是一个简单的操作

你有什么建议?每页向mongodb发送200个请求是否正常(必须以性能为目标)


或者可能是我遗漏了什么…

我将使用mongodb将用户id嵌入到注释中(这是“post”文档结构的一部分)

要获得更好的性能,有三个简单提示:

1) 确保用户id上有索引

2) 使用注释分页方法避免查询数据库200次


3) 缓存是您的朋友

您可以缓存用户对象,这样就不必每次都查询数据库

我喜欢在每篇文章中嵌入用户数据的想法,但是你必须考虑当用户的个人资料被更新时会发生什么?我们必须确保没有遗漏任何帖子

我建议您先浏览一下mongo建议您如何处理模式

通常,对于实体之间的“包含”关系, 应选择嵌入。如果不使用链接,则使用链接将导致 重复数据


使用-query可以避免数百个请求的
N+1
-问题。考虑这一点:

Post {
  PosterId: ObjectId
  Text: string
  Comments: [ObjectId, ObjectId, ...] // option 1
}

Comment {
  PostId: ObjectId // option 2 (better)
  Created: dateTime,
  AuthorName: string,
  AuthorId: ObjectId,
  Text: string
}
现在,您可以在查询中找到带有
$的帖子评论,还可以轻松找到特定作者的所有评论

当然,您也可以将注释作为嵌入数组存储在post中,并在获取注释时对用户信息执行
$in
查询。这样,您就不需要对用户名进行反规范化,也不需要数百次查询

如果您选择对用户名进行非规范化,则当用户更改(例如,他的姓名)时,您必须更新该用户所做的所有评论。另一方面,如果这样的行动不经常发生,那也没什么大不了的。或者,根据您的要求,最好存储用户发表评论时的姓名


嵌入的一般问题是,因此必须使用(例如
$push
)。这有时很难与映射器一起使用(但我不知道mongoalchemy),而且通常灵活性较差。

MongoDB文档中有一个非常好的用例:
方便的是,它也是用Python编写的:-)

谢谢,但在阅读了这篇官方文章之后,我决定嵌入它。现在,当项目增长时,用户对象得到扩展,并且已经两次遇到问题,注释对象缺少一些用户对象(不是推送所有数据,只是必要的)。嗯,事情变得一团糟。我当然知道他们的缓存。但考虑到性能,我更喜欢在缓存之前获得最佳效果,而不是使用缓存作为解决方案。唯一的区别是,我在评论中存储post_id,而不是在post中存储评论数组。因此,当文章被阅读时,我会额外请求获取评论。有几个问题可以确定您的意思:1)对于您的模式,也应该提出这个请求(使用$in而不是按post_id查找)?2) 我是否正确理解,您建议解析应该显示的注释数组,收集用户id,然后获得请求中包含额外$in的所有用户?所以,不管N条评论,总共有3条请求?我编辑了我的答案以澄清
Comment
现在有一个
PostId
,我认为这样更好。我担心您当前的模式是基于嵌入的。因此1)不需要,
中的
$in不是必需的,标准查询更好。2) 是的,您必须从注释中收集唯一的用户ID,然后获取这些用户,然后从(注释,用户)-对中创建视图模型。使用LINQ/.NET很容易,但在其他语言中可能很棘手。查询的数量是恒定的,正确的。