Bem, você pode usar mapReduce:
var mapper = function() {
function hot(ups,downs,date){
var score = ups - downs;
var order = log10(Math.max(Math.abs(score), 1));
var sign = score>0 ? 1 : score<0 ? -1 : 0;
var seconds = epochSeconds(date) - 1134028003;
var product = order + sign * seconds / 45000;
return Math.round(product*10000000)/10000000;
}
function log10(val){
return Math.log(val) / Math.LN10;
}
function epochSeconds(d){
return (d.getTime() - new Date(1970,1,1).getTime())/1000;
}
emit( hot(this.ups, this.downs, this.date), this );
};
E execute o mapReduce (sem um redutor):
db.collection.mapReduce(
mapper,
function(){},
{
"out": { "inline": 1 }
}
)
E, claro, presumindo que sua "coleção" tenha os campos para
ups
, downs
e date
. Claro que os "rankings" precisam ser emitidos de uma forma que seja "única", caso contrário você precisa de um "redutor" para classificar os resultados. Mas de um modo geral, isso deve fazer o trabalho.