1
votes

im currently starting with couchDB and have a problem building a reduce function on dates.

The database consists of timeline data for different locations. Every entry has a 'locationId' (String), a 'datetime' ( Array saved in lexicographic form like [year,month,day,hour,minute,sec]), a value (double)

i want to find out, which is the lowest and highest datetime for every location where a value exist. The timeline values have different start- and enddates.

In a first attempt i used _stats on milliseconds: map:

function(doc) { 
emit(doc.locationId, new Date(doc.datetime[0],doc.datetime[1],doc.datetime[2], doc.datetime[3], doc.datetime[4], doc.datetime[5]).getTime() ) }

reduce: _stats

this delivers the correct min and max milliseconds per locationId. Now i want to have the output in a more readable form (formatted date string)

I tried different ways, here is the last one: - map delivers locationId as key and a Date as value - reduce converts every Date to milliseconds, find the earlist date using Math.min, re-converting milliseconds into Date and return

map:

function(doc) {  
    emit(doc.locationId, new Date(doc.datetime[0], doc.datetime[1],doc.datetime[2], doc.datetime[3], doc.datetime[4], doc.datetime[5]) ) }

reduce:

function(keys, values) {
var timestamps = new Array(values.length);
var i = 0;
var date;
for( date in values ) { timestamps[i] = date.getTime(); i++; }
var min = Math.min.apply(null, timestamps);

return new Date(min);
}

This results in 'null' for value. is it possible to have a formatted date output for this case?

1

1 Answers

0
votes

I've found the solution:

map:

function(doc) { 
if (doc.datetime && doc.plantId) 
emit(doc.plantId, [new Date(doc.datetime[0],doc.datetime[1]-1,doc.datetime[2],doc.datetime[3],doc.datetime[4],doc.datetime[5],0), new Date()] ) 
}

reduce:

function(keys, values) {
values.sort();
var date = [values[0][0], values[values.length-1][0]]; 
return date;
}

result: (key=locationID, value=[earliestDate, latestDate])