Triage du mongodb par l'algorithme de classement reddit

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; }