Voici un code js pour classer les articles selon l'algorithme de classement de Reddit.
Ma question est la suivante: comment puis-je utiliser ce code pour classer mes documents mongodb?
( Algorithme de classement de Reddit )
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; }
Eh bien, vous pouvez utiliser 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 ); };
Et le run the mapReduce (sans réducteur):
db.collection.mapReduce( mapper, function(){}, { "out": { "inline": 1 } } )
Et bien sûr, en supposant que votre "collection" possède les champs pour les ups
, les downs
et la date
. Bien sûr, les «classements» doivent être émis d'une manière «unique», sinon vous avez besoin d'un «réducteur» pour trier les résultats.
Mais en général, cela devrait faire le travail.
Il y a un problème avec votre fonction:
new Date(1970, 1, 1) // Sun Feb 01 1970 00:00:00 GMT-0300 (BRT)
Oui, le mois 1 est février , et il utilise également le fuseau horaire des systèmes. Epoch dans JavaScript est
var epoch = new Date(Date.UTC(1970, 0, 1))
Depuis
epoch.getTime() // 0
La fonction
function epochSeconds(d){ return (d.getTime() - new Date(1970,1,1).getTime())/1000; }
Devrait être juste
function epochSeconds(d){ return d.getTime()/1000; }
En compressant un peu, cela renvoie exactement les mêmes résultats que la fonction python dans http://amix.dk/blog/post/19588
function hot (ups, downs, date){ var score = ups - downs; var order = Math.log(Math.max(Math.abs(score), 1)) / Math.LN10; var sign = score > 0 ? 1 : score < 0 ? -1 : 0; var seconds = (date.getTime()/1000) - 1134028003; var product = order + sign * seconds / 45000; return Math.round(product*10000000)/10000000; }