2014-03-29 12 views
5

Hier ist ein js-Code, um Elemente nach Reddit Ranking-Algorithmus Rang.Sortierung mongodb von reddit ranking algorithm

Meine Frage ist: Wie verwende ich diesen Code, um meine mongodb Dokumente zu ordnen?

(Reddit's ranking algorithm)

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

Yay, vielen Dank für die Buchung dieser Code! – wbarksdale

Antwort

8

Nun können Sie verkleinern verwenden:

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

}; 

und der Lauf der verkleinern (ohne Druckminderer):

db.collection.mapReduce(
    mapper, 
    function(){}, 
    { 
     "out": { "inline": 1 } 
    } 
) 

Und natürlich der Annahme, dass Ihre "Sammlung" hat die Felder für ups, downs und date. Natürlich müssen die "Rankings" auf eine Weise "einzigartig" ausgesendet werden, ansonsten benötigen Sie einen "Reducer", um die Ergebnisse zu sortieren.

Aber im Allgemeinen sollte das die Aufgabe erledigen.

+0

Was ist "Inline"? Können Sie die Reducer-Funktion verwenden? – Harry

3

Theres ein Problem mit Ihrer Funktion:

new Date(1970, 1, 1) // Sun Feb 01 1970 00:00:00 GMT-0300 (BRT) 

Yep, Monat 1 Februar ist, und es nutzt die Systeme Zeitzone auch. Epoche in JavaScript

ist
var epoch = new Date(Date.UTC(1970, 0, 1)) 

Seit

epoch.getTime() // 0 

Die Funktion

function epochSeconds(d){ 
    return (d.getTime() - new Date(1970,1,1).getTime())/1000; 
} 

function epochSeconds(d){ 
    return d.getTime()/1000; 
} 

ein wenig komprimieren gerade sein sollte, diese gibt genau das gleiche Ergebnisse als die Python-Funktion in 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; 
}