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

3

我正在设计一个使用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)

用户可以订阅从嵌入的订阅集合链接的Feed。通过订阅,我可以获得一个用户应该看到的所有Feed以及对应的条目列表。

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

  • 查找特定Feed的所有条目,其中isRead = 0或当前不存在状态
  • 对于特定用户,将发布日期早于某个时间点的所有条目标记为isRead = 1(这可能是数百甚至数千条记录,因此必须高效)
1个回答

2

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

对我来说,将未读条目的记录存储起来,然后在阅读后删除它们是有意义的。我基于这样的假设:每个用户已经阅读的文章比未读文章多,所以你最好不要让所有那些已经阅读过的条目一直存在于数据库中。如果你不需要随时随地拖着几年的历史记录,这也会使得避免16MB文档大小限制更容易。

对于标记为星标的条目,我只需向用户添加一个Entry ObjectIds数组即可。没有必要将其与订阅特定相关联;这样可以更轻松地拉出用户已经标记的列表。

对于未读条目,情况就有点复杂了。我仍然会将其添加为一个数组,但为了满足您能够快速标记在特定日期之前的已读条目的要求,我会将发布日期与Entry ObjectId一起去规范化,并保存在一个新的“UnreadEntry”文档中。

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拆分成自己的文档应该相当简单。)

现在两个查询都变得非常容易编写:

特定订阅源的所有未读条目: user.subscriptions.find(feedID).unread_entries

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

当然,如果您只需要将订阅源中的所有条目标记为已读,那么这非常容易实现: user.subscriptions.find(feedID).unread_entries.delete_all


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接