在MongoDB中,我正在尝试编写Map-Reduce函数,该函数仅在满足某些条件时才保存数据。
我不知道如何不从我的化简器发出()。它总是以一种或另一种方式保存数据。
下面是一个通用示例。忽略数据的上下文 - 我创建这些数据和代码只是为了这个问题的目的。
数据集:
{ "_id" : ObjectId("52583b3a58da9769dda48853"), "date" : "01-01-2013", "count" : 1 }
{ "_id" : ObjectId("52583b3d58da9769dda48854"), "date" : "01-01-2013", "count" : 1 }
{ "_id" : ObjectId("52583b4258da9769dda48855"), "date" : "01-02-2013", "count" : 1 }
{ "_id" : ObjectId("52583b4f58da9769dda48856"), "date" : "01-03-2013", "count" : 4 }
地图功能:
// Map all data by (date, count)
var map = function() {
var key = this.date;
var value = this.count;
emit(key, value);
}
简单地忽略不需要的数据的化简器。
// Only save dates which have count > 2
var reducer = function(date, counts) {
var sum = Array.sum(counts);
if (sum > 2) {
return sum;
}
}
结果(值 1 未被忽略):
{ "_id" : "01-01-2013", "value" : null }
{ "_id" : "01-02-2013", "value" : 1 }
{ "_id" : "01-03-2013", "value" : 4 }
我还添加了一个空的 return 语句,但得到了相同的结果:
// Only save dates which have count > 2
var reducer = function(date, counts) {
var sum = Array.sum(counts);
if (sum > 2) {
return sum;
}
else return;
}
我希望发生的事情是,在运行 Map-Reduce 后,我的输出集合中仅存在以下数据。我怎样才能做到这一点?
{ "_id" : "01-03-2013", "value" : 4 }
您可以运行一个额外的 mapReduce 操作,具有以下函数:
var second_map = function() {
if(this.value > 2) {
emit(this._id, this.value);
}
}
和
var second_reduce = function() {}
reduce 函数可以为空,因为每个键没有多个值将导致在这种情况下甚至无法调用它。
因此,运行mapReduce如下所示:
db.map_reduce_example.mapReduce(
second_map, second_reduce, {out: 'final_mapreduce_result'});
将生成以下集合:
> db.final_mapreduce_result.find()
{ "_id" : "01-03-2013", "value" : 4 }
请注意,如果您决定使用此方法,则可以从第一个 reduce 函数中删除if (sum > 2)
条件。
我们需要记住,如果键只有 1 个发出的值(来自 map()),则可以跳过化简器。 我们也不应该尝试过滤reduce中的结果,因为reduce可以针对同一键多次调用(每次都有发出的值的子集)。
唯一的其他选项是 finalize 方法,但这将导致空值而不是从结果中删除条目。
我认为获得所需结果的唯一方法是使用聚合框架而不是 map reduce。管道如下所示:
db.test.aggregate(
{
"$project" : {
"_id" : 0,
"date" : 1,
"count" : 1
}
},
{
"$group" : {
"_id" : "$date",
"value" : { "$sum" : "$count" }
}
},
{
"$match" : {
"value" : { "$gt" : 2 }
}
}
);
{ "result" : [ { "_id" : "01-03-2013", "value" : 4 } ], "ok" : 1 }
这种方法的唯一主要缺点是结果必须内联返回,这将结果的大小限制为 16MB。 这将在 2.6 版本中修复/补救:https://jira.mongodb.org/browse/SERVER-10097
呵呵,抢。