在MongoDb中使用MapReduce计算平均值

4

我有一个包含1000万条记录的集合,类似于这样。

{
    "_id" : ObjectId("596dd10bbd1a6628ace1c14c"),
    "X" : 13212,
    "Z" : 173836,
    "userID" : 9354785
}

用户ID是唯一的。我需要计算X的平均值和Z的总和。我可以使用以下MapReduce函数来计算Z的总和:

var mapFunction1 = function() {
emit(this.userID, this.Z);
};

var reduceFunction1 = function() {
return Array.sum(Z);
};

db.transaction.mapReduce(
mapfunction1, 
reduceFunction1,
{out:"mapreduce"}
)

如何计算X的平均值?

我尝试使用Array.avg(Z),但它返回与sum(Z)相同的输出。


标题说的是“Hadoop” MapReduce,但示例看起来像是MongoDB MapReduce。您能否澄清一下问题?是否涉及到Hadoop,还是这是一个MongoDB的问题? - Chris Nauroth
2个回答

2
看起来可以使用聚合管道$avg$sum运算符更简单地表达要求。

输入

> db.transactions.find()
{ "_id" : ObjectId("5970e59e26507421fa20bee9"), "X" : 13212, "Z" : 173836, "userID" : 9354785 }
{ "_id" : ObjectId("5970e5a426507421fa20beea"), "X" : 1234, "Z" : 5678, "userID" : 1 }
{ "_id" : ObjectId("5970e5a826507421fa20beeb"), "X" : 100, "Z" : 200, "userID" : 2 }

聚合管道
> db.transactions.aggregate([
    {
        $group : {
            _id: "aggregates",
            avgX: {
                $avg: "$X"
            },
            sumZ: {
                $sum: "$Z"
            }
        }
    }
])

输出

{ "_id" : "aggregates", "avgX" : 4848.666666666667, "sumZ" : 179714 }

1

您没有将(key,value)对参数传递给reduceFunction1。 尝试这个:

var mapFunction1 = function() {
emit(this.userID, this.Z);
};

var reduceFunction1 = function(varKey,varZ) {
return Array.avg(varZ);
};

db.transaction.mapReduce(
mapfunction1, 
reduceFunction1,
{out:"mapreduce"}
)

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