node.js - 架构:有效地计算和维护类似 Reddit 的网站中用户提交的分数

标签 node.js web-applications architecture redis software-design

在由用户提交驱动的类似 Reddit 的网站中,计算和维护实时故事排名的有效方法是什么?

每个提交都有一定的分数,由收到的赞成票、反对票和提交时间决定。 (较新的提交获得更高的排名)。虽然我有实现这背后的数学的想法,但我想知道如何最好地构建这样的东西,以便准确计算和维护提交的分数。

分数重新计算是否必须是通过后台作业的定期任务,或者分数是否仅在用户操作(如投票)时重新计算。

运行后台作业以定期间隔重新计算历史上每个提交的分数似乎效率非常低,而仅在赞成票/反对票/提交时重新计算分数并不能形成准确的排名系统(从那时起这样一来,一个故事就有可能在新的投票中失去得分)。

Web 应用程序的代码是用 Node.js 编写的,我使用的数据库是 Mongo 和 Redis(如果重要的话)。

我希望这个问题不要太笼统,如果是,请告诉我如何使它更精确。

最佳答案

我在以前工作的一家公司遇到了同样的问题。我认为你使用 redis 来存储分数是正确的,而且你对基本评分方法是正确的:“今天的投票比昨天的投票更有值(value),昨天的投票比前一天的投票更有值(value)”您可以通过让赞成票、反对票、提交等...都具有恒定分数来实现这一点,但为每个帖子保留“当前”和“以前”的分数窗口,并使用帖子的“当前”分数和“previous”分数来计算其“真实”分数。

我的意思是,让我们看看我们有一些我们称之为 A 的帖子,它在之前的评分窗口中获得了 1 个赞成票,在当前窗口中获得了 1000 个赞成票。然后你可以看出它明显的趋势并给它一个非常高的真实分数——比如 cur_score/prev_score 或类似的东西。同样,如果我们称为 B 的某个其他帖子在其前一个窗口中有 1000 个赞成票,但在其当前窗口中只有 1 个赞成票,我们知道它不再是趋势并给它一个惩罚性的低真实分数。这导致了一个非常好的结果,如果一个帖子出现在热源的顶部,它现在必须获得比过去一个小时更多的投票才能留在那里,所以东西会只有当它真正成为趋势时才停留在 Feed 的顶部,并且在看到更多、投票更多的反馈循环中,没有任何东西会停留在那里。

最后,对于当前窗口和上一个窗口本身,您基本上可以通过将当前窗口重置为空白并将上一个窗口设置为旧的当前窗口来每 n 分钟滚动一次。您可以在 Redis 中通过将每个窗口存储在 cur_windowprev_window 之类的散列中并且每隔 n 分钟仅 RENAME cur_window prev_window 当您准备好翻身了。这既便宜又高效,切中要害。

现在上面是一个粗略的草图,并没有涉及每个角落的案例和技术——这超出了 SO 答案的范围——但它确实解决了你遇到的能够计算的基本问题以不受帖子数量限制的方式得出趋势分数。

关于node.js - 架构:有效地计算和维护类似 Reddit 的网站中用户提交的分数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37050959/

相关文章:

node.js - 使用nodejs进行多人游戏的最佳实践

javascript - 它们如何代表电影在 imdb、烂番茄上的平均评分?

python - Google App Engine 在同一模型上获取和发布

javascript - 用于滚动/滑动的最佳 Javascript 库 (iPhone/iPad)

android - 如何查看android静态库的ABI?

javascript - Node.js process.exit() 不会在 createReadStream 打开时退出

javascript - gulp 观察者和 promise 导致崩溃

asp.net - 网络开发 : What is the best way to do a multi-file upload?

architecture - 在 DDD 架构中,我在哪里保留帮助类?

java - 我应该创建许多单例或单例上下文来引用我的状态和对象吗?