Mongodb - Map-Reduce - 不返回完整数据

时间:2013-07-05 09:51:51

标签: mongodb mapreduce

我正在使用Map Reduce。问题是,如果没有。 <文件输入> 100,然后我没有得到预期的没有。结果,但如果没有。输入文件的数据是&lt; = 100,然后我按预期得到结果。

我收到的示例输出:

{
    "_id" : "5504",
    "value" : [
            ObjectId("51c921bae4b0f0f776b339d2"),
            ObjectId("51b06b5be4b021e44bc69755")
    ]
}

问题:如果有&lt; = 100个用户的文档(ID:5504),那么我会得到那么多。输出数组中的ids但是如果没有。文件&gt; 100,然后我在输出数组中得到很少的ID。当没有时,我得到了上面的输出。这个用户的文件是101,但是当它是100,我有100个ID。为什么这种奇怪的行为以及解决方案是什么?

地图功能:

db.system.js.save({

    _id: "map1",

    value: function () {
        var value = {
            "data": [{
                "_id": this._id,
                "creation_time": this.creation_time
            }]
        };
        emit(this.user_id, value);
    }
});

减少功能

db.system.js.save({

    _id: "reduce1",

    value: function (key, values) {
        var reducedValue = [];
        for (var i = 0; i < values.length; i++) {
            reducedValue.push({
                "_id": values[i].data[0]._id,
                "creation_time": values[i].data[0].creation_time
            });
        }
        return {
            data: reducedValue
        };
    }
});

完成功能:

db.system.js.save({

    _id: "finalize1",

    value: function (key, reducedValue) {
        var a = reducedValue.data.sort(compare1);
        var ids = [];
        for (var i = 0; i < a.length; i++) {
            ids.push(a[i]._id);
        }
        return ids;
    }
});

比较功能

db.system.js.save({

    _id: "compare1",

    value: function (a, b) {
        if (a.creation_time < b.creation_time) return 1;
        if (a.creation_time > b.creation_time) return -1;
        return 0;
    }
});

MapReduce()调用

db.notifications.mapReduce(map1, reduce1, {out: "notifications_result", query: {delivered:true, user_id:"5504"}, finalize: finalize1});

1 个答案:

答案 0 :(得分:1)

由于MongoDB可以多次调用reduce函数,因此必须确保Function Idempotence。对reduce函数稍作修改即可解决问题:

db.system.js.save({

    _id: "reduce1",

    value: function (key, values) {
        var reducedValue = [];
        for (var i = 0; i < values.length; i++) {
            for(var j = 0; j < values[i].data.length; j++) {
                reducedValue.push({
                    "_id": values[i].data[j]._id,
                    "creation_time": values[i].data[j].creation_time
                });   
            }

        }
        return {
            data: reducedValue
        };
    }
});

请注意,现在也会遍历values[i].data数组,因为其他reduce1调用的返回are in the values array