Instead of returning the average from your reduce function, return the
sum and length. Something like:
if (rereduce) {
var total_sum = 0;
var total_length = 0;
for (var i = 0; i < values.length; i++) {
total_sum += values[i][0];
total_length += values[i][1];
}
return [total_sum, total_length];
} else {
return [sum(values), values.length];
}
Now client-side you can do the division of sum and length to get the
average. This gives you a true average instead of an average of
averages which you've already seen is not the same.
Ben
On Sun, Aug 30, 2009 at 6:27 AM, Jan Lehnardt wrote:
>
> On 30 Aug 2009, at 11:36, Francisco Viramontes wrote:
>
>> Hi list!
>>
>> I hava a question about grouping and the reduce function
>>
>> If aI want to average the sum of manu values returned by my map function
>> on a large database (~100000 rows ) the reduce function gets called with the
>> rereduce boolean
>>
>> The thing is a am not sure if its mathematically correct to average sets
>> of floats in groups as optimized by couch where I can have to average
>> smaller sets of previously averaged values. I certainly dont get the exact
>> same result of averaging a whole set than a grouped set.
>>
>> My question is how can I handle my reduce function to reduce a whole set
>> and not in groups?
>>
>> Note the emit call is done with complex keys:
>>
>> map:
>>
>> function(doc) {
>> if ((doc['couchrest-type'] == 'RawData') &&
>> doc['device_variable_id']) {
>> date = new Date(doc.date_time);
>> emit([doc.device_variable_id, date.getFullYear(),
>> date.getUTCMonth() + 1, date.getUTCDate(), date.getUTCHours(),
>> parseInt(date.getUTCMinutes() / 20 + 1) ], doc.value);
>> }
>> }
>>
>> reduce:
>>
>> function( keys, values, rereduce ) {
>> if(rereduce){
>> log("rereduce");
>> }
>> return sum( values ) / values.length ;
>> }
>
> You cannot ignore the call where rereduce is true. See
> http://svn.apache.org/viewvc/couchdb/trunk/share/www/script/test/reduce.js?revision=804727&content-type=text%2Fplain
>
> scroll down a little:
>
> " var reduceCombine = function (keys, values, rereduce) { "
>
> for an example.
>