在MongoDb中使用map-reduce进行挣扎

时间:2013-11-07 10:19:06

标签: mongodb mapreduce

问题

我有一个_id的文档和Answers的集合我正在尝试编写一个map-reduce函数来汇总每个id的答案总分。

文档

/* 0 */
{
  "_id" : ObjectId("527b6ba88d251d58a18f3f0a"),
  "Answers" : [{
      "Score" : 2
    }, {
      "Score" : 0
    }, {
      "Score" : 2
    }, {
      "Score" : 2
    }]
}

这是Map-Reduce我虽然阅读文档是正确的

地图

function() {
    this.Answers.forEach(function(val)
    { 
        emit(this._id, val.Score); 
    });
}

也试过这个

function() {

    for (var i = 0; i < this.Answers; i++)
    { 
        emit(this._id, this.Answers[i].Score); 
    }
}

减少

function(key, values) 
{
    return Array.sum(values);
}

我没有得到任何关于此的信息,但它似乎正在处理它需要2-5秒才能返回。我想我不了解map-reduce。

我也使用MongoVUE来访问MongoDB。

修改

我只是通过控制台运行我的地图缩小并获得此输出

{
        "results" : [ ],
        "timeMillis" : 2506,
        "counts" : {
                "input" : 1655,
                "emit" : 0,
                "reduce" : 0,
                "output" : 0
        },
        "ok" : 1,
}

所以这是我的地图功能不正确我想是没有发出任何东西。

编辑2

使用mongovue

的输出更新了文档

2 个答案:

答案 0 :(得分:1)

在JavaScript循环中添加length属性允许您迭代数组中项目的计数,因此您可以将第二次尝试更改为:

function() {

    for (var i = 0; i < this.Answers.length; i++)
    { 
        emit(this._id, this.Answers[i].Score); 
    }
}

还应该注意,你的reduce可以每个键运行多次,特别是它可以重复每101行,从技术上讲,这应该无关紧要,因为你总结了数组值,之前的reduce值将作为一个传递新的数组元素减少所以它应该工作得很好;但是,请记住这一点。

答案 1 :(得分:1)

我认为'this'变量不是你在map方法中的.forEach()函数中所期望的。试试这个;

function() {
    var row = this;
    this.Answers.forEach(function(val)
    { 
      emit(row._id, val.Score); 
    });
}