将函数应用于MongoDB中的集合中的所有对象的最有效方法是什么?

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

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

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

如果你打开其他想法如何计算知名度,有更多的select:)。

提高效率

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

  • 将您的更新标准限制为拥有0票以上的文档(否则无论如何您都会得到零分)
  • 只检索您需要计算stream行度的字段,并用$set更新stream行度字段,而不是重新保存完整的文档。
  • 当您添加个人投票(避免每小时对所有分数进行完整的重新计算),然后对所有选票进行不太频繁的(例如每晚)重新计算时更新人气分数

替代方法

  • 使用可以通过sorting而不是计算来确定的stream行度度量。 例如: { votes: -1, lastVotedTime: -1, submitTime: -1 } 。 尽pipe如此,这可能不能满足您对旧文档stream行度的要求。

  • 在事件和用户操作(例如文章发布,用户观看/投票/ …)中使用数字stream行度度量会添加不同的stream行度值。 随着时间的stream逝衰退。 Drupal的Radioactivity模块使用基于规则的方法来实现这一点。

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

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

“什么是良好的stream行度度量”还有更多的细微差别,以及关于StackOverflow的很多以前的问题(例如: 应该用什么公式来确定“热门”问题? )。