MongoDB Map Reduce - 使用Finalize跳过一些结果

6
我有一个适用于集合的MapReduce函数,如下所示:
function Map() {
    emit (
        this.name, 
        { 
            count : 1,
            flag : this.flag

        }
    );
}
function Reduce(key, values) {
    var count = 0;
    var flag = false;

    for (var i in values){
        count = count + 1;
        if (i.flag)
             flag = true;
    }

    var reduced = {
        count : count,
        flag  : flag
    }
    return reduced;
}
function Finalize(key, reduced) {

    if (reduced.count>10 || reduced.flag){
        var finalized = {
            "count" : reduced.count 
        }
        return reduced;
    }

    return null;
}

我试图做的是,仅在对象满足某个阈值(如count>10)时才返回Finalize。目前它仍在返回对象,但计数只是null。
有什么想法?
2个回答

3
我建议你使用聚合框架,因为它更快且更易于理解。你上面的 M/R/F 可以很容易地写成以下形式:
db.so.insert( { name: "Derick" } );
db.so.insert( { name: "Derick" } );
db.so.insert( { name: "Derick" } );
db.so.insert( { name: "Derick" } );
db.so.insert( { name: "Checklist" } );
db.so.insert( { name: "Checklist" } );
db.so.insert( { name: "Whoop" } );
db.so.insert( { name: "Whoop", flagged: true } );
db.so.aggregate( [
    { $group: { 
        _id: '$name', 
        count: { $sum: 1 }, 
        flagged: { $sum: 
            { $cond: [ { $eq: [ '$flagged', true ] }, 1, 0 ] } 
        } 
    } },
    { $match: { $or: [ { count: { $gt: 3 } }, { flagged: { $gt: 0 } } ] } }
] );

这将返回:

{
    "result" : [
        {
            "_id" : "Whoop",
            "count" : 2,
            "flagged" : 1
        },
        {
            "_id" : "Derick",
            "count" : 4,
            "flagged" : 0
        }
    ],
    "ok" : 1
}

谢谢Derick。我不能使用聚合,因为在map/reduce中还有一些逻辑,为了简化问题,我没有放进去。 - checklist
请在问题中提供这个... A/F比你想象的更强大! - Derick
我已经添加了一个更复杂的示例,其中计数应该大于3或者其中一个项目被标记。 - checklist
我已经为您修复了匹配问题... $match只是一个查询。 - Derick
这并没有解决mapReduce finalize过滤器问题,该问题需要进行复杂操作,或者至少比aggregate处理的更加复杂。 - jmdiego

2
你无法取消键,只能更改值的格式。Finalize只会更改你的值的格式,但无法取消键(实际上是由map阶段发出的)。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接