Taking an Average in CouchDB

More fun with CouchDB, this time taking an average of something:
// map
function(doc){
    emit(null, doc.info.size) // in place of doc.info.size, you'd put whatever
                               // value you want averaged here
}
// reduce
function(keys, values, rereduce) {
    if (!rereduce){
        var length = values.length
        return [sum(values) / length, length]
    }else{
        var length = sum(values.map(function(v){return v[1]}))
        var avg = sum(values.map(function(v){
            return v[0] * (v[1] / length)
            }))
        return [avg, length]
    }
}
The end result will be 2 values, the first is the average, the second is the total number of values that we took an average of. Phew! Who woulda thought taking an average would be so involved!
Wout Mertens said about 1 year ago
So I understand you're doing it this way to avoid overflows, but aren't you stacking up division errors instead?

Perhaps the only accurate way to do this would be to store the results as strings and use an unlimited-precision math library like http://www-cs-students.stanford.edu/~tjw/jsbn/

Leave Comment

optional