码迷,mamicode.com
首页 > 数据库 > 详细

MongoDB中通过MapReduce实现合计Sum功能及返回格式不一致问题分析

时间:2015-02-05 17:56:08      阅读:275      评论:0      收藏:0      [点我收藏+]

标签:

建立下述测试数据,通过MapReduce统计每个班级学生数及成绩和。

技术分享

代码如下:

public string SumStudentScore()
{
    var collection = _dataBase.GetCollection("StudentInfo");

    //按照班级(Class)进行分组统计,并将每条记录的记录数(1)和成绩(this.Score)作为Reduce参数
    string mapFunction = @"function(){
                                            emit(this.Class,{Count:1,Score:this.Score});
                                        };";

    //注意此处Values是分组后的一到多条记录
    string reduceFunction = @"function(Class,Values){
                                            var reduced = {SumCount:0,SumScore:0};
                                                    
                                            Values.forEach(function(val){
                                                reduced.SumCount += val.Count;
                                                reduced.SumScore += val.Score;
                                            });
                                            return reduced;
                                        }";

    string outputInfo = string.Empty;
    var result = collection.MapReduce(mapFunction, reduceFunction);

    foreach (var item in result.GetResults())
    {
        outputInfo += item.ToString() + Environment.NewLine;
    }

    return outputInfo;
}

执行结果如下:

{ "_id" : "11班", "value" : { "SumCount" : 2.0, "SumScore" : 9.0 } }
{ "_id" : "12班", "value" : { "SumCount" : 2.0, "SumScore" : 8.0 } }
{ "_id" : "13班", "value" : { "Count" : 1.0, "Score" : 5.0 } }

可见统计结果没有问题,但是第三个分组13班的返回格式明显不同于前两条,经查阅资料为误用MapReduce所致,MapReduce使用有如下要求:

Reduce方法的Value参数必须与返回结果一致。

再分析上述代码:

Reduce的Values参数是由Map方法emit而来,因此参数格式为:{Count:Number,Score:Number},而Reduce的返回参数格式为:{SumCount:Number,SumScore:Number},格式并不一致,因此导致了上述问题。

修改上述代码,将emit结果与Reduce返回格式保持一致:

public string SumStudentScore()
{
    var collection = _dataBase.GetCollection("StudentInfo");

    //按照班级(Class)进行分组统计,并将每条记录的记录数(1)和成绩(this.Score)作为Reduce参数
    string mapFunction = @"function(){
                                            emit(this.Class,{SumCount:1,SumScore:this.Score});
                                        };";

    //注意此处Values是分组后的一到多条记录
    string reduceFunction = @"function(Class,Values){
                                            var reduced = {SumCount:0,SumScore:0};
                                                    
                                            Values.forEach(function(val){
                                                reduced.SumCount += val.SumCount;
                                                reduced.SumScore += val.SumScore;
                                            });
                                            return reduced;
                                        }";

    string outputInfo = string.Empty;
    var result = collection.MapReduce(mapFunction, reduceFunction);

    foreach (var item in result.GetResults())
    {
        outputInfo += item.ToString() + Environment.NewLine;
    }

    return outputInfo;
}

输出结果正确:

{ "_id" : "11班", "value" : { "SumCount" : 2.0, "SumScore" : 9.0 } }
{ "_id" : "12班", "value" : { "SumCount" : 2.0, "SumScore" : 8.0 } }
{ "_id" : "13班", "value" : { "SumCount" : 1.0, "SumScore" : 5.0 } }

参考资料:

关于《来,我给你们看一段神奇的mongodb的mapreduce操作!》的解释

db.collection.mapReduce() — MongoDB Manual 2.6.7

MongoDB中通过MapReduce实现合计Sum功能及返回格式不一致问题分析

标签:

原文地址:http://www.cnblogs.com/ndaysy/p/4275186.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!