1

假设我想计算我的集合中所有对象的“流行度”字段。这取决于当前时间与“submitTime”字段的差异以及“votes”字段中的数字。此操作将每小时运行一次。在所有对象上运行函数的最有效方法是什么?只是一个例子,它可以是任何函数:

function(){
    this.popularity = this.votes / (Date.now() - this.submitTime);
}
4

1 回答 1

1

如果您想对所有对象运行一个函数并在原始集合中保存一个流行度分数,那么您最好的方法是迭代所有文档以计算并保存新分数。如果你想保存到不同的集合,你可以使用MapReduce代替。

如果您对如何计算流行度的其他想法持开放态度,还有更多选择:)。

提高效率

为了提高您当前方法的效率,您可以:

  • 将您的更新标准限制为票数超过 0 的文档(否则无论如何您都会被零除)
  • 仅检索计算流行度所需的字段,并使用 a$set而不是重新保存完整文档来更新流行度字段。
  • 添加个人投票时更新受欢迎程度得分(避免每小时重新计算所有得分),然后对所有投票进行不那么频繁(例如每晚)重新计算

替代方法

  • 使用可以通过排序而不是计算来确定的流行度指标。例如:{ votes: -1, lastVotedTime: -1, submitTime: -1 }。但是,这可能无法满足您对旧文档的流行度进行老化的要求。

  • 使用数字流行度指标,其中事件和用户操作(例如文章发布、用户查看/投票/、..)将添加不同的流行度值。随着时间的推移,人气会下降。Drupal的Radioactivity 模块通过基于规则的方法实现了这一点。

要在 MongoDB 中实现后一种方法,您可以:

  • 添加一个整数popularity字段,其中新对象从某个值开始(例如 1000)
  • 让不同的用户操作(新投票、视图等)$inc以适当的数量增加受欢迎程度计数器(例如 50 个新投票)
  • 随着时间的推移,使用定期安排的工作来降低受欢迎程度。
  • 由于所有流行度都以正分数开始并衰减到 0 或更低,因此您可以将更新查询限制为流行度 >0 的文档。
  • 您还可以(ab)使用流行度分数来确保重要文档保持流行更长时间。

“什么是好的流行度指标”还有更多细微差别,以及 StackOverflow 上的大量先前问题(例如:应该使用什么公式来确定“热门”问题?)。

于 2013-04-07T06:47:38.177 回答