1

我有一个User实体,其中包含他/她正在关注的其他用户 ID 数组。

var userSchema = {
  following: { type: Array }
};

我有一个 RESTful API,当我请求一个 时User,我的应用程序需要知道有多少关注者User

我看到的两个选项是:

  • User请求 a 时,进行计数查询,例如:{ following: { $in: [userId] } }
  • 当 aUserPOST编辑时,检查是否有任何用户 ID 被添加或删除到following数组中,如果是,使用 MongoDB$inc来增加或减少文档上已被关注/取消关注的followersCount属性。User

他们还有其他选择吗?如果没有,最好的选择是什么?我觉得followersCount在文档本身中放置一个属性有点奇怪,因为这表明它可以由应用程序更新,而实际上它只是一个动态计数。

我有类似的情况,我需要我的 RESTful API 返回articlewebsite. 我是否应请求计算该网站的文章,还是存储计数属性并在每次创建与该网站关联的新文章时更新它?

4

2 回答 2

0

你想做的方式就是正确的方式。MongoDB 之类的优点之一是您可以嵌入数据以减少您需要在页面上运行的查询。这就是您通过缓存关注者数量所做的事情。

您的两种选择都有效,这只是您想要做出的权衡。

1)效率较低,但最准确。当他们下一次关注某人时,任何以某种方式发生的不同步都会被修复。这是一种不错的开始方式,然后如果关注者人数较多或用户数据库变大,稍后再进行更改。

2) 最有效的是,您需要确保在更改关注者数量时始终调用 $inc ,否则它将变得不同步,直到您执行 #1。

或者,您可以执行 #2,然后在后台运行协调作业,如果它确实变得不同步,它将重新同步它。您可以使用MongoDB 聚合框架轻松完成此操作,您可以通过使用集合中的时间戳来加速协调作业,User并且仅重新计算自上次作业运行以来更新的追随者。

随着原始问题的更新而扩展:

一般来说,如果你可以避免做 a count(),你应该这样做。

开始使用count()然后切换到更有效的解决方案(#2)没有任何问题。将结果缓存在count()诸如 memcache 之类的地方也可用于减少性能问题,直到您count()直接停止使用。

于 2013-05-14T23:09:20.220 回答
0

不要害怕在文档中存储比您认为需要的更多的数据。当我开始按照 mongo 而不是 RDMS 的思路思考时,我从思考normalize everything中解脱出来。它允许我在文档中添加更多“有用”的信息,即使它不是绝对必要的。文档中的事务很便宜,存储成本也相对便宜。在另一个文档或集合中查找信息的成本是昂贵的(处理明智的),如果可以的话,可能值得减少。

我理解您对“应用程序可以编辑”的数据库计数的担忧。所以呢?确保您的应用程序无法对其进行编辑,并且如果您的 API 对世界开放,请确保他们也无法对其进行编辑。“缓存”计数的有用性远远超过了它可能被编辑和不同步的事实。这是使用 nosql 数据库的危险之一:事情最终可能会不同步,因为我们信任应用程序代码来保持数据井井有条,而不是依赖数据库。

考虑一下。如果用户被删除,并且计数没有更新怎么办。这会给用户带来不同的世界吗?可能不是。虽然我喜欢后台任务来检查值的想法(并且值得拥有类似的东西),但另一种解决方案是每次用户向关注者发布内容时检查完整性。在这种情况下,无论如何您都必须获得所有用户,因此检查计数也相对便宜。本质上,您正在构建一个故障保护,每次从用户发送消息时都会检查数据完整性。如果用户从不发送,则该用户可能不在乎计数是否 100% 准确。

归根结底,如果您的代码经过了良好的测试,并且遵循了防御性编码实践,那么您就不应该有任何一致性问题。

于 2013-06-17T14:25:06.000 回答