用于博客的mongodb架构设计

kef*_*hou 29 database-design mongodb

您将如何为具有基于文档的数据库(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",
}
Run Code Online (Sandbox Code Playgroud)

Gat*_* VP 33

Article {
  "_id" : "A",
  "title" : "Hello World",
  "user_id" : 12345,
  "text" : 'My test article',

  "comments" : [
    { 'text' : 'blah', 'user_id' : 654321, 'votes' : [987654]},
    { 'text' : 'foo', 'user_id' : 987654, 'votes' : [12345, 654321] },
    ...
  ]
}
Run Code Online (Sandbox Code Playgroud)

这里的基本前提是我已经嵌套了Comments内部Article.该Votes只适用于一个Comment,所以他们已经被存储为每一个阵列Comment.在这种情况下,我刚刚存储了user_id.如果要存储更多信息(time_created等),则可以对一组对象进行投票:

... 'votes' : [ { user_id : 987654, ts : 78946513 } ] ...
Run Code Online (Sandbox Code Playgroud)

如何有效地执行查询:

  1. 获得A条评论,评论A条和每条评论的票数
db.articles.find( { _id : 'A' } )
Run Code Online (Sandbox Code Playgroud)

这通过一个查询获得所有内容.你可能不得不做一些客户端逻辑来计算每条评论的投票数,但这非常简单.

  1. 获取用户B对所有文章的所有评论
db.articles.ensureIndex( { "comments.user_id" : 1 } )
db.articles.find( { "comments.user_id" : 987654 } ) // returns all document fields
Run Code Online (Sandbox Code Playgroud)

该索引将允许有效地搜索文档中的注释.

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

db.articles.find( { "comments.user_id" : 987654 }, { "title" : 1, "comments.user_id" : 1 })
Run Code Online (Sandbox Code Playgroud)
  1. 获得用户B投票的所有评论
db.articles.ensureIndex( { "comments.votes" : 1 } )
db.articles.find( { "comments.votes" : 987654 } )
Run Code Online (Sandbox Code Playgroud)

同样,这将返回所有文章,而不仅仅是评论.

这里有一个权衡取舍.返回文章似乎我们正在带回太多数据.但是,当您进行查询#3时,您计划向用户显示什么?

如果没有评论本身,获取"我投票的评论"列表并不是非常有用.当然,没有文章本身(或至少只是标题),评论就没有用.

大多数情况下,查询#3将转换为from Votesto Commentsto Articles.如果是这样,那么为什么不把这些文章带回来呢?

  • 16MB /文件的限制怎么样? (5认同)