假设我想计算我的集合中所有对象的“流行度”字段。这取决于当前时间与“submitTime”字段的差值以及“votes”字段中的数字。该操作每小时运行一次。在所有对象上运行函数的最有效方法是什么?只是一个例子,它可以是任何函数:
function(){
this.popularity = this.votes / (Date.now() - this.submitTime);
}
最佳答案
如果您想对所有对象运行函数并在原始集合中保存流行度分数,则最好的方法是迭代所有文档以计算并保存新分数。如果您想保存到不同的集合,您可以使用 MapReduce相反。
如果您愿意接受有关如何计算受欢迎程度的其他想法,还有更多选择:)。
提高效率
为了提高当前方法的效率,您可以:
- 将更新条件限制为投票数超过 0 票的文档(否则无论如何您都会被除以零)
- 仅检索计算流行度所需的字段,并使用
$set
更新流行度字段。而不是重新保存完整文档。 - 在添加个人投票时更新受欢迎度分数(避免每小时完全重新计算所有分数),然后对所有投票进行不太频繁的重新计算(例如每晚)
替代方法
使用可以通过排序而不是计算来确定的流行度指标。例如:
{ votes: -1, lastVotedTime: -1, SubmitTime: -1 }
。不过,这可能无法满足您对旧文档的流行程度进行老化的要求。使用数字流行度指标,其中事件和用户操作(例如发布的文章、用户 View /投票/,..)将添加不同的流行度值。随着时间的推移,人气逐渐下降。 Radioactivity module for Drupal使用基于规则的方法来实现这一点。
要在 MongoDB 中实现后一种方法,您可以:
- 添加一个整数
流行度
字段,其中新对象以特定值(例如 1000)开始 - 通过不同的用户操作(新投票、观点等)增加受欢迎程度计数器
$inc
适当的金额(例如新投票 50) - 使用定期安排的作业来随着时间的推移降低受欢迎程度。
- 由于所有流行度都以正分数开始,然后衰减到 0 或更低,因此您可以将更新查询限制为流行度 >0 的文档。
- 您还可以(ab)使用受欢迎度分数来确保重要文档更长时间地受欢迎。
对于“什么是好的流行度指标”还有更多细微差别,StackOverflow 上也有很多之前的问题(例如: What formula should be used to determine “hot” questions? )。
关于javascript - 将函数应用于 MongoDB 集合中的所有对象的最有效方法是什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15856736/