【发布时间】:2016-02-24 17:14:02
【问题描述】:
我需要使用一个临时变量在 reduce 函数中临时存储值。在我的输出日志中,结果显示 reduce 函数运行的次数为 0。但是,一旦我执行其他类型的计算,它就会运行。
当我执行代码时,reduce 函数无法访问 prev 对象。如果有任何帮助,我正在为 nodejs 使用 mongojs 库。
var map = function() {
emit(this._id,
{
d1: this.day_chan1,
d2: this.day_chan2,
d3: this.day_chan3
});
};
var reduce = function(key, values) {
var data = {};
var curr = values[0];
data.d1 = curr.d1 - prev.d1;
data.d2 = curr.d2 - prev.d2;
data.d3 = curr.d3 - prev.d3;
prev = curr;
return { timestamp: key , data: data };
};
var prev = { d1: 0, d2: 0, d3: 0 };
this
.db
.mapReduce(
map,
reduce,
{
scope: { prev : prev },
sort: { timestamp: 1 },
query: {},
out: 'temp'
}
,
function (err, data) {
if(err) callback(err);
else callback(data);
});
这是我正在处理的数据样本
{
"_id" : ObjectId("5650845744aeea3dba90326d"),
"timestamp" : "2015-09-21 05:02:52",
"curr_property" : NumberInt(1818),
"curr_property_cost" : NumberInt(21),
"day_property" : NumberInt(30),
"day_property_cost" : NumberInt(18),
"curr_solar_generating" : NumberInt(676),
"curr_solar_export" : NumberInt(0),
"day_solar_generated" : NumberInt(11),
"day_solar_export" : NumberInt(0),
"curr_chan1" : NumberInt(676),
"curr_chan2" : NumberInt(676),
"curr_chan3" : NumberInt(466),
"day_chan1" : NumberInt(11),
"day_chan2" : NumberInt(11),
"day_chan3" : NumberInt(7),
"gatewayId" : 23.0
}
{
"_id" : ObjectId("5650845744aeea3dba90326e"),
"timestamp" : "2015-09-21 05:03:52",
"curr_property" : NumberInt(1818),
"curr_property_cost" : NumberInt(21),
"day_property" : NumberInt(60),
"day_property_cost" : NumberInt(18),
"curr_solar_generating" : NumberInt(676),
"curr_solar_export" : NumberInt(0),
"day_solar_generated" : NumberInt(22),
"day_solar_export" : NumberInt(0),
"curr_chan1" : NumberInt(676),
"curr_chan2" : NumberInt(676),
"curr_chan3" : NumberInt(466),
"day_chan1" : NumberInt(22),
"day_chan2" : NumberInt(22),
"day_chan3" : NumberInt(15),
"gatewayId" : 23.0
}
{
"_id" : ObjectId("5650845744aeea3dba90326f"),
"timestamp" : "2015-09-21 05:04:52",
"curr_property" : NumberInt(1818),
"curr_property_cost" : NumberInt(21),
"day_property" : NumberInt(91),
"day_property_cost" : NumberInt(19),
"curr_solar_generating" : NumberInt(676),
"curr_solar_export" : NumberInt(0),
"day_solar_generated" : NumberInt(33),
"day_solar_export" : NumberInt(0),
"curr_chan1" : NumberInt(676),
"curr_chan2" : NumberInt(676),
"curr_chan3" : NumberInt(466),
"day_chan1" : NumberInt(33),
"day_chan2" : NumberInt(33),
"day_chan3" : NumberInt(23),
"gatewayId" : 23.0
}
这是我日志中的输出
{
"result" : "temp",
"timeMillis" : 3362,
"counts" : {
"input" : 39781,
"emit" : 39781,
"reduce" : 0,
"output" : 39781
},
"ok" : 1
}
这是临时集合在操作后的样子
{
"_id" : ObjectId("5650845744aeea3dba90326d"),
"value" : {
"d1" : 11.0,
"d2" : 11.0,
"d3" : 7.0
}
}
{
"_id" : ObjectId("5650845744aeea3dba90326e"),
"value" : {
"d1" : 22.0,
"d2" : 22.0,
"d3" : 15.0
}
}
{
"_id" : ObjectId("5650845744aeea3dba90326f"),
"value" : {
"d1" : 33.0,
"d2" : 33.0,
"d3" : 23.0
}
}
这是我希望得到的东西
{
"_id" : ObjectId("5650845744aeea3dba90326d"),
"value" : {
"d1" : 0,
"d2" : 0,
"d3" : 0
}
}
{
"_id" : ObjectId("5650845744aeea3dba90326e"),
"value" : {
"d1" : 11.0,
"d2" : 11.0,
"d3" : 9.0
}
}
{
"_id" : ObjectId("5650845744aeea3dba90326f"),
"value" : {
"d1" : 11.0,
"d2" : 11.0,
"d3" : 18.0
}
}
我正在努力解决这个问题,非常感谢一些帮助。
更新:
代码当前在 mongojs 的服务方法中运行。这是在 mongo 控制台中的等价物。
db.testdb.mapReduce(map,
reduce,
{
scope: { prev : prev },
sort: { timestamp: 1 },
query: {},
out: 'temp'
});
map 和 reduce 方法的声明与顶部相同。
【问题讨论】:
-
您能否编辑您的问题,向我们展示以下三个可能会增加您获得正确答案的机会的要素;一些示例文档、实际输出和您的预期结果?
-
@chridam 刚刚更新。
-
你能把 prev 放在 reduce 函数上面吗?
-
@Ravenous 我已经这样做了。我仍然得到相同的结果
-
@Bazinga777 因此,尽管您的地图功能可以做它想做的事情并发出它想要的东西,但我将 mapreduce 功能解释为一件事。 “MongoDB 不会为只有一个值的键调用 reduce 函数。值参数是一个数组,其元素是“映射”到键的值对象。” docs.mongodb.org/manual/reference/command/mapReduce/…
标签: node.js mongodb scope mapreduce