Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/node.js/36.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database design 博客的mongodb模式设计_Database Design_Mongodb - Fatal编程技术网

Database design 博客的mongodb模式设计

Database design 博客的mongodb模式设计,database-design,mongodb,Database Design,Mongodb,您将如何设计基于文档数据库(mongodb)的类似博客的站点的模式。该网站有以下对象:用户、文章、评论。用户可以在文章中添加评论。每个用户也可以在每条评论中投票一次 我希望能够高效地执行这些查询: 1.获取文章A、对文章A的评论以及每条评论的投票数 2.获取用户B对所有文章的所有评论 3.获取用户B投票支持的所有评论 我的第一个尝试是将文章和评论放在不同的集合中,而评论可以包含投票支持它的用户列表。这使得查询1和查询2变得简单。对于3,我添加了投票收集功能,可以跟踪用户的投票 有一些明显的缺点,

您将如何设计基于文档数据库(mongodb)的类似博客的站点的模式。该网站有以下对象:用户、文章、评论。用户可以在文章中添加评论。每个用户也可以在每条评论中投票一次

我希望能够高效地执行这些查询:
1.获取文章A、对文章A的评论以及每条评论的投票数
2.获取用户B对所有文章的所有评论
3.获取用户B投票支持的所有评论

我的第一个尝试是将文章和评论放在不同的集合中,而评论可以包含投票支持它的用户列表。这使得查询1和查询2变得简单。对于3,我添加了投票收集功能,可以跟踪用户的投票

有一些明显的缺点,比如重复用户投票数据,查询1需要对数据库进行两次调用。有更好的方法吗

Article {
  "user_id"
}

Comment {
   "user_id",
   "article_id",
   [user_voted],
}

Vote {
    "user_id",
    "comment_id",
}
这里的基本前提是我将
注释嵌套在
文章
中。
投票
仅适用于
注释
,因此它们与每个
注释
一起存储为一个数组。在本例中,我刚刚存储了用户id。如果您想存储更多信息(创建时间等),则可以对一组对象进行投票:

... 'votes' : [ { user_id : 987654, ts : 78946513 } ] ...
如何高效地执行查询:

  • 获取文章A、对文章A的评论以及每个评论的投票数
  • 这将通过一个查询获取所有信息。您可能需要执行一些客户端逻辑来计算每条评论的投票数,但这非常简单

  • 获取用户B对所有文章的所有评论
  • 该索引将允许有效地搜索文档中的注释

    目前无法仅从子数组中提取匹配项。此查询实际上将返回该用户的所有带有注释的文章。如果这可能是太多的数据,您可以做一些修剪

    db.articles.find( { "comments.user_id" : 987654 }, { "title" : 1, "comments.user_id" : 1 })
    
  • 获取用户B投票支持的所有评论
  • 同样,这将返回所有文章,而不仅仅是评论

    这里需要做一个权衡。返回文章可能看起来我们带回了太多的数据。但是,在进行查询3时,您打算向用户显示什么

    如果没有评论本身,获取“我投票支持的评论”列表就没有多大用处。当然,如果没有文章本身(或者至少只有标题),评论就没有多大用处


    大多数情况下,查询#3会从
    投票
    转移到
    评论
    文章
    。如果是这样的话,那么为什么不把文章放回原处呢?

    16MB/文档的限制是什么?如果你担心一篇博客文章超过16MB(这是很多文本),那么你需要进行不同的模式设计。许多博客实际上将其作为单独的查询来源,因此他们实际上不会同时访问这两个部分。如果这是你的担忧,那么你可以选择一个不同的模式。我需要一个类似的博客设计,我需要从所有文章中获取按日期排序的评论,以供审核。现在,这个结果也应该分页。我还是应该坚持这种体系结构,还是将评论部分放到另一个集合中?如果您计划从文章中单独查询评论,那么它应该有自己的集合。MongoDB中的建模应该围绕“顶级”对象。如果您只打算在文章中查询注释,那么可以使用上面的模式。如果您计划单独查询注释,则需要将其拆分。(注意,选票的嵌套可能仍然有效)实际上,我还担心单个文档的局限性。这就是为什么我不敢像上面的模式那样将它们放在一起,而不是将它们分成两个文档并建立简单的关系。
    db.articles.find( { _id : 'A' } )
    
    db.articles.ensureIndex( { "comments.user_id" : 1 } )
    db.articles.find( { "comments.user_id" : 987654 } ) // returns all document fields
    
    db.articles.find( { "comments.user_id" : 987654 }, { "title" : 1, "comments.user_id" : 1 })
    
    db.articles.ensureIndex( { "comments.votes" : 1 } )
    db.articles.find( { "comments.votes" : 987654 } )