【问题标题】:Mongodb and MapReduce - results missingMongodb 和 MapReduce - 结果丢失
【发布时间】:2014-04-11 10:35:48
【问题描述】:

使用此代码:

var map = function(){

    emit(1, { read: this.read, important: this.important, count: 1 })
}

var reduce = function(key, vals) {

    var i = 0, r = 0, c = 0;

    vals.forEach(function(d) {
       r += !d.read ? 0 : 1;
       i += d.important ? 0 : 1
       c += d.count;
    });

    return { read: r, important: i, count: c }
}

db.ipdr.mapReduce(map, reduce, { out: "__mr_test", verbose: true, query: { liid: "40001" } });
db.getCollection("__mr_test").find();

我的计数不完整:

{
    "_id" : 1,
    "value" : {
        "read" : 1,
        "important" : 7,
        "count" : 7607
    }
}

“计数”是可以的,但“阅读”和“重要”应该高很多。我错过了什么吗?

【问题讨论】:

    标签: javascript mongodb mapreduce aggregation-framework


    【解决方案1】:

    这不是 mapReduce 的好用法。聚合框架使用比 JavaScript 执行速度快得多的本地代码,并且可以完成相同的工作。假设“阅读”和“重要”是逻辑值,即:

    db.posts.aggregate([
        { "$sort": { "read": 1, "important": 1 } },
        { "$group": {
            "_id": null,
            "read": { "$sum": { "$cond": [ "$read", 1, 0 ] } },
            "important": { "$sum": { "$cond": [ "$important", 1, 0 ] } },
            "count": { "$sum": 1 }
        }}
    ])
    

    因此不仅速度更快,而且编码更简单。

    给定示例文档:

    { "read" : true,  "important" : false }
    { "read" : true,  "important" : false }
    { "read" : false, "important" : false }
    { "read" : false, "important" : true  }
    { "read" : true,  "important" : true  }
    

    结果是:

    { "_id" : null, "read" : 3, "important" : 2, "count" : 5 }
    

    【讨论】:

    • 我希望这可行,但所有这些“$”字符看起来更丑。 :) 不是 agg。在底层使用 mapreduce 的框架?
    • @dakt 不,它是直接在 C++ 代码中实现的。 mapReduce 使用 JavaScript 解释器(现代版本为 v8)。所有$ 符号都是聚合框架如何定义它的运算符和引用字段的变量,以便将它们与有效字段名称区分开来,由于显而易见的原因,它们不能以$ 开头。
    • 感谢赐教。我非常确定 AF 是由 MapReduce 驱动的。所以应该完全避免?
    • @dakt 应该使用 mapReduce 是有实际正当理由的,或者目前必须使用其他方式来解决特定问题。作为答案的一部分,我所指出的只是存在更好的替代方案的地方,然后使用它。由于聚合框架是后来引入的,因此很可能存在可以通过聚合框架更好地实现的遗留用途。
    • @dakt 我做了一个小的编辑以及一个工作示例。即使您远离实际数据,也没有理由不接受。
    【解决方案2】:

    而不是

    r += !d.read ? 0 : 1;
    i += d.important ? 0 : 1
    c += d.count;
    

    你不应该有

    r += !d.read ? 0 : d.read;
    i += d.important ? 0 : 1
    c += d.count;
    

    【讨论】:

    • 现在我得到“读取”的正确结果,但是当我删除“!”我得到 0 这是不正确的......
    • 如果您可以提供示例数据和预期输出,那么它可以以更好的方式回答,但是也请查看聚合框架。它更快更好。
    • 假设每个文档都包含: { read: Boolean, important: Boolean } 以及其他字段。
    猜你喜欢
    • 2014-07-18
    • 1970-01-01
    • 2015-03-24
    • 1970-01-01
    • 1970-01-01
    • 2012-06-29
    • 2015-09-27
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多