【问题标题】:Mongo Map Reduce errorMongo Map Reduce 错误
【发布时间】:2013-04-12 10:03:00
【问题描述】:

作为 MongoDB 的新手,我正在尝试调用 MapReduce。 不幸的是,我收到以下错误:

mongos> db.events.mapReduce(m,r,"errors");
Fri Apr 12 11:39:15.637 JavaScript execution failed: map reduce failed:{
    "ok" : 0,
    "errmsg" : "MR parallel processing failed: { errmsg: \"exception: reduce -> multiple not supported yet\", code: 10075, ok: 0.0 }"
} at src/mongo/shell/collection.js:L970
mongos> 

我使用的是 Mongo 2.4.0

我的事件集合如下所示:

{ "sid" : "1UADM45MCGRTW ", "time" : ISODate("2013-04-08T11:33:13.229Z"), "class" : "S", "service" : "service1" }
{ "sid" : "1UADM45MCGRTW ", "time" : ISODate("2013-04-08T11:33:13.229Z"), "class" : "I", "service" : "service1" }
{ "sid" : "1UADM45MCGRTW ", "time" : ISODate("2013-04-08T11:33:13.236Z"), "class" : "E", "text" : "error message" }
{ "sid" : "1UADM45MCGRTW ", "time" : ISODate("2013-04-08T11:33:13.239Z"), "class" : "F", "service" : "service1" }

{ "sid" : "1UDO3H7YUOK08 ", "time" : ISODate("2013-04-08T11:33:08.095Z"), "class" : "S", "service" : "service2" }
{ "sid" : "1UDO3H7YUOK08 ", "time" : ISODate("2013-04-08T11:33:08.095Z"), "class" : "I", "service" : "service2" }
{ "sid" : "1UDO3H7YUOK08 ", "time" : ISODate("2013-04-08T11:33:08.173Z"), "class" : "E", "text" : "another error message" }
{ "sid" : "1UDO3H7YUOK08 ", "time" : ISODate("2013-04-08T11:33:08.188Z"), "class" : "F", "service" : "service2" }

{ "sid" : "1UDO3JVXIS2UZ ", "time" : ISODate("2013-04-08T11:28:39.480Z"), "class" : "I", "service" : "service1" }
{ ""sid" : "1UDO3JVXIS2UZ ", "time" : ISODate("2013-04-08T11:28:39.480Z"), "class" : "S", "service" : "service1" }
{ "sid" : "1UDO3JVXIS2UZ ", "time" : ISODate("2013-04-08T11:28:40.853Z"), "class" : "F", "service" : "service1" }
{ "sid" : "1UDO3JVXIS2UZ ", "time" : ISODate("2013-04-08T11:28:40.852Z"), "class" : "I", "service" : "service1" }

我的目的是获取所有“E”条目并将它们与“F”条目的相应“sid”的“服务”字段结合起来。所以这应该很简单,但我做不到(因为上面的错误)。

我使用的 map/reduce 函数是:

var m = function() {
    if (this.class == "E") {
        value = { time: this.time, error: this.text };
        emit(this.sid, value);
    } else if (this.class == "F") {
        value = { service: this.service };
        emit(this.sid, value);
    }
}


var r = function(key,values) {
    return values;
}

db.events.mapReduce(m,r,"errors");

【问题讨论】:

    标签: mongodb mapreduce


    【解决方案1】:

    问题是你想累积每个键的所有错误,这意味着你必须发出一个文档数组,然后你的 reduce 必须将它们组合成一个数组(因为它将接收一个数组数组)。

    您遇到的另一个问题是您希望将每个唯一 cid 的不同类组合成一些组合的缩减结果,但您的缩减函数甚至没有尝试这样做。

    很难知道每个 sid 可能获得多少不同的类值,但如果它就像您提供的示例数据一样,我猜您想要这样的东西:

    var m = function() {
        array = [];
        if (this.class == "E") {
            value = { time: this.time, error: this.text };
            array.push(value);
            emit(this.sid, {a:array});
        } else if (this.class == "F") {
            value = { service: this.service };
            array.push(value);
            emit(this.sid, {a:array});
        }
    }
    
    
    var r = function(key,values) {
        result = {a:[]};
        values.forEach(function (v) {
           result.a = v.a.concat(result.a);
        });
        return result;
    }
    
    db.events.mapReduce(m,r,"errors");
    

    在您的示例中,生成的集合将如下所示:

    > db.errors.find().pretty()
    {
        "_id" : "1UADM45MCGRTW ",
        "value" : {
            "a" : [
                {
                    "service" : "service1"
                },
                {
                    "time" : ISODate("2013-04-08T11:33:13.236Z"),
                    "error" : "error message"
                }
            ]
        }
    }
    {
        "_id" : "1UDO3H7YUOK08 ",
        "value" : {
            "a" : [
                {
                    "service" : "service2"
                },
                {
                    "time" : ISODate("2013-04-08T11:33:08.173Z"),
                    "error" : "another error message"
                }
            ]
        }
    }
    {
        "_id" : "1UDO3JVXIS2UZ ",
        "value" : {
            "a" : [
                {
                    "service" : "service1"
                }
            ]
        }
    }
    

    您可能可以添加一个 finalize 函数来将此数组转换为单个文档的结果,但这取决于您想要拥有的结果集合的格式以及每个 sid 的预期输入。

    【讨论】:

      【解决方案2】:

      根据文档 (troubleshoot reduce function) "reduce 函数必须返回一个对象,其类型必须与 map 函数发出的值的类型相同"

      当您发出一个对象时,reduce 也应该发出一个对象 - 所以将 values 包装在一个对象中,您应该可以开始了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-06-02
        • 1970-01-01
        • 1970-01-01
        • 2016-03-13
        • 1970-01-01
        • 2021-01-28
        • 2014-01-14
        • 1970-01-01
        相关资源
        最近更新 更多