如何在mongodb mapreduce中实现需要非关联reducer的计算
How to implement calculation that needs non-associative reducer in mongodb mapreduce
问题最好举例说明:
一个集合包含一个文档对应一个事件,事件可以是"Start" 事件或某个程序的"Stop" 事件。
比如程序A在时间12:00开始运行的时候,写了一个文档
{ program_name: 'A', time: 12:00, event: 'Start' }
当它在 12:10 处结束时,它会写入另一个文档
{ program_name: 'A', time: 12:10, event: 'Stop' }
所以在集合中有很多对不同程序的启停文档。
如何通过map reduce计算每个程序的运行时间?
例如map和reducer函数是:
function map() {
emit( this.program_name, { time: this.time, event: this.event} )
}
function reduce(key, values) {
var timeElapsed = 0
if ( values[0].event == 'Start' ) {
timeElapsed = values[1].time - values[0].time
}
else {
timeElapsed = values[0].time - values[1].time
}
return timeElapse;
}
上面的实现给出了我想要做什么的想法,但是它违反了许多 rules 说的关联、幂等和交换。
如何实现符合 mongodb reducer 规则的 mapreduce,或者在 mapreduce 方法中不可能这样做?
reduce函数可以是这样的:
function reduce(key, values) {
return values.reduce((res, e) => Object.assign({[e.event]:e.time}, res, e), {})
}
数学应该在finalize函数中完成:
function(key, reducedValue) {
return reducedValue.Stop - reducedValue.Start;
}
问题最好举例说明:
一个集合包含一个文档对应一个事件,事件可以是"Start" 事件或某个程序的"Stop" 事件。
比如程序A在时间12:00开始运行的时候,写了一个文档
{ program_name: 'A', time: 12:00, event: 'Start' }
当它在 12:10 处结束时,它会写入另一个文档
{ program_name: 'A', time: 12:10, event: 'Stop' }
所以在集合中有很多对不同程序的启停文档。
如何通过map reduce计算每个程序的运行时间?
例如map和reducer函数是:
function map() {
emit( this.program_name, { time: this.time, event: this.event} )
}
function reduce(key, values) {
var timeElapsed = 0
if ( values[0].event == 'Start' ) {
timeElapsed = values[1].time - values[0].time
}
else {
timeElapsed = values[0].time - values[1].time
}
return timeElapse;
}
上面的实现给出了我想要做什么的想法,但是它违反了许多 rules 说的关联、幂等和交换。
如何实现符合 mongodb reducer 规则的 mapreduce,或者在 mapreduce 方法中不可能这样做?
reduce函数可以是这样的:
function reduce(key, values) {
return values.reduce((res, e) => Object.assign({[e.event]:e.time}, res, e), {})
}
数学应该在finalize函数中完成:
function(key, reducedValue) {
return reducedValue.Stop - reducedValue.Start;
}