mongoDB map / reduce减去reduce

时间:2010-08-27 03:05:03

标签: mongodb

我有一些25k文件(原始json中为4 GB)的数据,我想执行一些javascript操作,以使我的终端数据使用者(R)更容易访问,我想通过为每个更改添加一个新集合,“版本控制”这些更改,但我无法弄清楚如何map/reduce没有reduce。我想要一对一的文档映射 - 我在collection_1开始使用25,356个文档,我想在collection_2中得到25,356个文档。

我可以用这个来破解它:

var reducer = function(key, value_array) {
    return {key: value_array[0]}
}

然后称之为:

db.flat_1.mapReduce(mapper, reducer, {keeptemp: true, out: 'flat_2'})

(我的映射器只调用emit一次,字符串作为第一个参数,最后一个文件作为第二个参数。它是我真正想要的那些第二个参数的集合。)

但这看起来很尴尬,我不知道它为什么会起作用,因为我的映射器中的emit调用参数不等同于reducer的返回参数。另外,我最终得到了像

这样的文档
{
    "_id": "0xWH4T3V3R", 
    "value": {
        "key": {
            "finally": ["here"],
            "thisIsWhatIWanted": ["Yes!"]
        }
    }
}

这似乎没必要。

此外,执行自己的插入的游标甚至不到mapReduce的十分之一。我不太了解MongoDB以对它进行基准测试,但我猜它会慢一点50x。有没有办法并行运行游标?我不在乎collection_2中的文档与collection_1中的文档顺序不同。

5 个答案:

答案 0 :(得分:6)

使用map / reduce时,你总是会以

结束
{ "value" : { <reduced data> } }

要删除value密钥,您必须使用finalize功能。

以下是将数据从一个集合复制到另一个集合的最简单方法:

map = function() { emit(this._id, this ); }
reduce = function(key, values) { return values[0]; }
finalize = function(key, value) { db.collection_2.insert(value); }

然后当你正常运行时:

db.collection_1.mapReduce(map, reduce, { finalize: finalize });

答案 1 :(得分:3)

  

但这似乎很尴尬,我不知道它为什么会起作用,因为我的映射器中的emit调用参数不等同于reducer的返回参数。

它们是等价的。 reduce函数接收T个值的数组,并且应以相同的T格式返回单个值。 T的格式由地图功能定义。 reduce函数只返回values数组中的第一个项,它始终是T类型。这就是它起作用的原因:))

你似乎走在了正确的轨道上。我做了一些实验,似乎你不能从map函数中做db.collection.save(),但你可以从reduce函数中做到这一点。您的地图功能应该只是构建您需要的文档格式:

function map() {
  emit(this._id, { _id: this.id, heading: this.title, body: this.content });
}

map函数重用原始文档的ID。这应该可以防止任何重新减少步骤,因为没有值将共享相同的密钥。

reduce函数可以简单地返回null。但此外,您可以将值写入单独的集合

function reduce(key, values) {
  db.result.save(values[0]);

  return null;
}

现在db.result应该包含已转换的文档,而不会在临时集合中添加任何额外的map-reduce噪音。我实际上没有对大量数据进行测试,但这种方法应该利用map-reduce函数的并行执行。

答案 2 :(得分:1)

当你有权访问mongo shell时,它接受一些Javascript命令然后它更简单:

map = function(item){
        db.result.insert(item);
}

db.collection.find().forEach(map);

答案 3 :(得分:0)

答案 4 :(得分:0)

我遇到了同样的情况。我能够通过Mongo查询和投影来实现这一目标。见Mongo Query

相关问题