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

我希望能够高效地执行这些查询:

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

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

Article {
  "user_id"
}

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

Vote {
    "user_id",
    "comment_id",
}

推荐答案

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] },
    ...
  ]
}

这里的基本前提是,我将Comments嵌套在Article中.Votes只适用于Comment,因此它们被存储 for each Comment的array.在本例中,我刚刚存储了用户id.如果您想存储更多信息(创建时间等),则可以对一组对象进行投票:

... 'votes' : [ { user_id : 987654, ts : 78946513 } ] ...

如何高效地执行查询:

  1. 获取文章A、对文章A的 comments 和#每条 comments 的投票数
db.articles.find( { _id : 'A' } )

只需一个查询就可以获取所有信息.你可能需要做一些客户端逻辑来计算每条 comments 的投票数,但这是非常琐碎的.

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

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

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

db.articles.find( { "comments.user_id" : 987654 }, { "title" : 1, "comments.user_id" : 1 })
  1. 获取用户B投票支持的所有 comments
db.articles.ensureIndex( { "comments.votes" : 1 } )
db.articles.find( { "comments.votes" : 987654 } )

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

这里需要做一个权衡.退回这篇文章似乎我们带回了太多的数据.但是,当你进行查询时,你打算向用户显示什么?

如果没有 comments 本身,获得"comments I've voted for"人的名单并不是非常有用.当然,如果没有文章本身(或者至少只有标题), comments 就没有多大用处.

大多数情况下,查询#3会从VotesComments再到Articles转化为一个连接.如果是这样的话,那为什么不把文章带回来呢?

Mongodb相关问答推荐

$mod只支持数字类型,不支持MongoDb中的array和int

MongoDB Aggregate:查找每个月的交叉日期范围的数量

如何在Golang保存到MongoDB时排除空数据值的问题?

MongoDB - 分组并找到前 N 个

使用名为 Object 键的 uuid 创建 mongodb 文档

如何在 MongoDB 中进行内部连接?

mongoose递归填充

如何知道 MongoDB 集合大小?

django 和 mongodb 是否使迁移成为过go ?

如何使用 mongodb 和 php 正确处理分页查询?

mongodb-nodejs-driver,DeprecationWarning:collection.count 已弃用

MongoDB GridFS VS 直接磁盘 IO

使用已排序的数据获取不同的值

MongoDB:查询和检索嵌入式数组中的对象?

使用自定义 _id 值时 mongodb 中的 Upserts

Mongodb $lookup 使用 _id 无效果

MongoDb:聚合 $lookup 过滤外部文档

对于社交网站(使用 Ruby on Rails 开发)来说,MongoDB 会是一个好主意吗?

MongoError:failed to connect to server [localhost:27017] on first connect

mongodb & max connections最大连接数