如何检测MongoDB map/reduce中的re-reduce阶段?
How to detect the re-reduce stage in MongoDB map/reduce?
我使用以下 map/reduce 设置将一些数据收集到数组中:
map: function() { emit(this.key, [this.item]); },
reduce: function(key, values) {
var items = [];
values.forEach( function(value) {items.concat(value.item);} );
return items;
},
out: {reduce: "result_collection"}
我想改进代码并检测生成的集合在重新归约阶段是否已更改(当 mongo 使用 "result_collection" 的当前内容调用归约时)。
换句话说,如何知道 Map 发出的任何文档包含 "item" 而 "result_collection" 中还不存在(当然,在相同的键下)?
此信息可以在某些进一步的处理阶段提供帮助,例如查询 "result_collection" 以获取在 map/reduce 阶段更新的文档。
如果一定要这样做,在所有reduction完成后使用finalize
函数调整value
。您必须向 reduce 函数添加更多逻辑来处理修改后的输出。
我将向您展示一个示例,其中包含由以下 map
和 reduce
函数定义的简单 map-reduce:
var map = function() { emit(this.k, this.v) }
var reduce = function(key, values) { return Array.sum(values) }
在看起来像 { "k" : 0, "v" : 1 }
的文档上,由上述函数定义的 map-reduce 生成看起来像 { "_id" : 0, "value" : 17 }
的结果文档。定义一个finalize
函数来修改最终文档:
var finalize = function (key, reducedValue) { return { "m" : true, "v" : reducedValue } }
现在修改 reduce
来处理 values
的一个元素,它可能是上述形式的对象:
var reduce2 = function(key, values) {
var sum = 0;
for (var i = 0; i < values.length; i++) {
if (typeof values[i] == "object") { sum += values[i].v }
else { sum += values[i] }
}
return sum
}
输出看起来像
{ "_id" : 0, "value" : { "m" : true, "v" : 14 } }
{ "_id" : 1, "value" : { "m" : true, "v" : 34 } }
{ "_id" : 2, "value" : { "m" : true, "v" : 8 } }
这样您就可以知道 value.m
修改了什么。您的进一步处理可以将 v.m
设置为 false
这样您将在每次 map-reduce 后看到尚未处理的内容。
我使用以下 map/reduce 设置将一些数据收集到数组中:
map: function() { emit(this.key, [this.item]); },
reduce: function(key, values) {
var items = [];
values.forEach( function(value) {items.concat(value.item);} );
return items;
},
out: {reduce: "result_collection"}
我想改进代码并检测生成的集合在重新归约阶段是否已更改(当 mongo 使用 "result_collection" 的当前内容调用归约时)。
换句话说,如何知道 Map 发出的任何文档包含 "item" 而 "result_collection" 中还不存在(当然,在相同的键下)?
此信息可以在某些进一步的处理阶段提供帮助,例如查询 "result_collection" 以获取在 map/reduce 阶段更新的文档。
如果一定要这样做,在所有reduction完成后使用finalize
函数调整value
。您必须向 reduce 函数添加更多逻辑来处理修改后的输出。
我将向您展示一个示例,其中包含由以下 map
和 reduce
函数定义的简单 map-reduce:
var map = function() { emit(this.k, this.v) }
var reduce = function(key, values) { return Array.sum(values) }
在看起来像 { "k" : 0, "v" : 1 }
的文档上,由上述函数定义的 map-reduce 生成看起来像 { "_id" : 0, "value" : 17 }
的结果文档。定义一个finalize
函数来修改最终文档:
var finalize = function (key, reducedValue) { return { "m" : true, "v" : reducedValue } }
现在修改 reduce
来处理 values
的一个元素,它可能是上述形式的对象:
var reduce2 = function(key, values) {
var sum = 0;
for (var i = 0; i < values.length; i++) {
if (typeof values[i] == "object") { sum += values[i].v }
else { sum += values[i] }
}
return sum
}
输出看起来像
{ "_id" : 0, "value" : { "m" : true, "v" : 14 } }
{ "_id" : 1, "value" : { "m" : true, "v" : 34 } }
{ "_id" : 2, "value" : { "m" : true, "v" : 8 } }
这样您就可以知道 value.m
修改了什么。您的进一步处理可以将 v.m
设置为 false
这样您将在每次 map-reduce 后看到尚未处理的内容。