MongoDB在共享集合对象上存储特定于用户的数据

时间:2011-11-07 02:52:16

标签: mongodb schema mongoid

我正在设计一个使用MongoDB处理RSS提要的应用程序。目前我的收藏品如下:

Entry
fields: content, feed_id, title, publish_date, url

Feed
fields: description, title, url

User
fields: email_address
subscriptions (embedded collection; fields: feed_id, tags)

用户可以订阅从嵌入式订阅集合链接的订阅源。从订阅中,我可以获得用户应该看到的所有订阅源的列表以及相应的条目。

我应该如何存储特定于用户的条目状态信息(isRead,isStarred等)?当用户查看我需要记录的条目isRead = 1.我需要能够执行的两个常见查询是:

  • 查找特定Feed的所有条目,其中isRead = 0或当前不存在任何状态
  • 对于特定用户,使用isRead = 1标记发布日期之前的所有条目(这可能是数百甚至数千条记录,因此必须高效)

1 个答案:

答案 0 :(得分:2)

嗯,这是一个棘手的问题!

对于我来说,为未读的条目存储记录是有意义的,并在读取它们时删除它们。我的基础是假设每个用户都有更多的阅读帖子而不是未阅读,所以你可能也没有永久存在于你的数据库中的所有已阅读条目的文档。如果您不必随处乱动多年的历史记录,也可以更轻松地担心16MB的文档大小限制。

对于已加星标的条目,我只需向User添加一个Entry ObjectIds数组。无需使这些订阅特定;提取一个用户以这种方式加注的项目列表会更容易。

对于未读条目,它有点复杂。我仍然将它添加为数组,但是为了满足您在特定日期之前能够快速标记读取条目的要求,我将在新的“UnreadEntry”中对Entry ObjectId进行非规范化并保存发布日期。文档。

User
fields: email_address, starred_entries[]
subscriptions (embedded collection; fields: feed_id, tags, unread_entries[])

UnreadEntry
fields: id is Entry ObjectId, publish_date

你需要意识到文档限制,但是16MB是很多未读条目/提要中的一个,所以要确定这是否是你真正需要担心的限制。 (如果是,将User.subscriptions分解为自己的文档应该相当简单。)

现在,您的两个查询都变得相当容易:

未读取的特定Feed的所有条目: user.subscriptions.find(feedID).unread_entries

在发布日期之前标记所有条目: user.subscriptions.find(feedID).unread_entries.where(publish_date.lte => my_date).delete_all

当然,如果您只需将Feed中的所有条目标记为已读,则非常简单: user.subscriptions.find(feedID).unread_entries.delete_all