【问题标题】:Best way to model a voting system in MongoDB在 MongoDB 中建模投票系统的最佳方法
【发布时间】:2011-10-26 03:56:04
【问题描述】:

我正在尝试在 MongoDB 中为投票系统建模。你可以把它想象成一个类似于 reddit 的投票系统。要求:

  1. 投票与对象相关
  2. 检查用户是否对某个对象进行了投票非常快。应用程序需要知道登录用户是否对某个对象进行了投票,同时它会遍历呈现投票按钮的对象列表。
  3. 最重要的是,它必须能够以合理的性能检索在给定时间段(最后一小时、一天、一个月等)内按总分数排序的对象。
  4. 应该能够支持每个对象数千票。

我在这里看到了两种方法(如果我错了,请纠正我!):

  1. 在每个对象中嵌入一组投票文档。我可能会存储投票用户的 ObjectId、投票数量和投票时间。 voterId 将是投票数组中每个嵌入式投票文档的键,以允许快速查找哈希。
  2. 保留一个单独的投票集合,其中包含引用对象的投票。

我还尝试过将投票嵌入到单独集合中按小时分组的“桶”中。

没有。对于要求 2 来说,1 会非常快,但我不知道在这种情况下要求 3 是否可能。

没有。对于要求 2,2 会慢一些,我不确定要求 3 的性能如何/如何实现(地图减少?)。

基本上,我似乎需要从第 3 项要求的合理快速解决方案开始,然后确保第 2 项要求不会太慢。想法?


潜在解决方案

使用嵌入式方法。为每个对象添加一个参数,用于每小时得分、每日得分、每月得分等。添加另一个布尔参数最近投票、最近每小时和最近每天。创建一个脚本,在对象上运行 map-reduce 以计算和更新这些参数。

该脚本将通过 cron 以三种变体形式运行。

  1. 10 分钟间隔:计算先前每小时得分 > 0 或最近投票的对象的每小时得分 = true。运行此脚本后设置最近投票= false。设置最近每小时 = true。
  2. 3 小时间隔:计算最近每小时 = true 的任何对象的每日得分。设置最近每小时 = 假。设置最近的每日 = true。
  3. 24 小时间隔:计算最近每天 = true 的任何对象的每月得分。设置最近的每日 = 假。

这个想法是尽量减少对与正在运行的分数计算脚本无关的对象的不必要处理(每小时应该只对自上次每小时运行以来已经投票的对象运行,或者没有已投票,需要重置为 0)。另一个不错的好处是 *-score 值不仅仅需要根据对象投票来计算。例如,您可以包括页面浏览量或其他任何内容。对这种方法有什么想法?

【问题讨论】:

  • 好问题。我使用过 mongoDB,可能会给你一个可能很糟糕的解决方案,但我期待看到人们提出什么想法。
  • 我确信您尝试在 Mongo 中执行此操作是有充分理由的,但考虑到要求,我认为在具有传统数据仓库索引策略的传统关系数据库将胜过它(并且仅将星型模型作为主要数据模型,无需从传统的规范化模型转移到数据仓库或类似的东西),并且不需要常规的 cron 作业- 很好地处理#3(这是星型模式擅长的)

标签: database-design mongodb


【解决方案1】:

查看 Mongo Cookbook 中的原子操作符投票方法:http://cookbook.mongodb.org/patterns/votes/。它没有告诉您如何实现聚合,但您也许可以通过制作代表要投票的对象的替代对象来做到这一点,但要针对特定​​的时间段。

【讨论】:

  • 嗯,是的,我读过那篇文章和其他一些文章。他们都建议解决方案 1(嵌入式)。但是,它们并没有解决更棘手的聚合问题。我想不出一种相当快速的方法来使用 mongo ad-hoc。到目前为止,我已经想到了通过 cron / map-reduce 进行后台处理。
  • 我在同一个故事中。但是发现你的回答很有帮助,因为有很多与之相关的模式:)谢谢队友。
  • 菜谱现在好像没了,但页面还在 Wayback Machine 中:web.archive.org/web/20130620101300/http://cookbook.mongodb.org/…(菜谱源还在 github 上:github.com/mongodb/cookbook
【解决方案2】:

如果您使用 ruby​​,则有一个用于 Mongoid 和 MongoMapper 的 votable_mongo 插件。

【讨论】:

  • 我正在使用 PHP,但问题是如何在 mongodb 中组织这种类型的系统的更普遍的问题。我将研究 votable_mongo 是如何做到的,看看那里是否有潜在的答案。
  • 好的,我看了一下。它是上述解决方案 1 的一个版本。它似乎没有为要求 3(最重要/最困难的要求)提供可行的解决方案。
猜你喜欢
  • 1970-01-01
  • 2015-03-16
  • 1970-01-01
  • 1970-01-01
  • 2021-09-27
  • 2015-02-22
相关资源
最近更新 更多