MongoDB - 子子孩子?

时间:2015-12-27 14:32:40

标签: mysql node.js mongodb

在像StackOverflow这样的应用程序中(没有什么真正相关,但它是一个很好的例子),我们有Question个。我们的mongodb集合中的每个Question都有一个Answer s数组,以及一个Vote s数组(无论是upvoting还是downvoting)。

在每个Answer中,User可能会对其进行投票或投票。

因此架构看起来像这样:

Question
  -> Answers []
     -> Votes []
        -> value (-1/1)
        -> username
  -> Votes []
     -> value (-1/1)
     -> username       
  -> question_text, etc.

来自MySQL背景,这种架构感觉“icky”,但我确信这是一种行业惯例。

现在我需要向每位用户展示他们投票的内容,包括QuestionAnswer

因此,如果我必须找到用户投票的Answer,我会查询(在节点中):

question_collection.find(
     {'question.answers.votes.username': username}, function(e,d) {
    /* do stuff */}
 );

该查询深入4级。这是一种正常的方法,还是应该在模式中引入一些规范化?

1 个答案:

答案 0 :(得分:1)

MongoDB的一个优点是,您可以将Question的所有相关信息放在一个文档中,因此您只需要1个数据库查询而不需要连接来获取所有信息以呈现Question

但是,如果您想查找用户投票的所有内容,事情会变得复杂一些。当然,你可以做你做的事,虽然它不会赢得任何表现奖。

或者,您可以以更智能的方式复制数据,以便更轻松地访问它。例如,您可以向User模型添加两个数组:

QuestionsVoted: [{ id1: +1}, {id2: -1}, {id3: +1}],
AnswersVoted: [{ id4: +1}, {id5: -1}]

这意味着您需要保持这些数据同步:当用户对问题或答案进行投票时,您需要更新问题和用户。这并不是那么糟糕,因为数据写得很少并经常阅读。

如果您有其他要求处理投票本身的要求,例如一段时间内投票的统计数据,或按地理区域,您可能需要创建一个Vote集合。是的,您必须在3个集合中保持数据同步。

技术上可以在MongoDB中创建外键,但在这种情况下我不建议使用它。你会失去MongoDB的一些好处,因为它不擅长连接(它需要2个单独的查询)。

您可以阅读有关如何在MongoDB on their blog中设计关系的更多信息。