• MongoDB(课时29 MapReduce)


    3.7.4 MapReduce

    MapReduce 是整个大数据的精髓所在(实际中别用,因为在MongoDB中属于最底层操作)。

    MapReduce是一种计算模型,简单的说就是将大批量的工作分解执行,然后再将结果合并成最终结果。

    MapReduce 就是分为两步处理数据:

    • Map:将数据分别取出
    • Reduce:负责数据的最后的处理

    范例:建立一组雇员数据

    db.emps.insert({"name": "张三", "age": 30, "sex": "", "job": "CLERK", "salary": 1000});
    db.emps.insert({"name": "李四", "age": 28, "sex": "", "job": "CLERK", "salary": 5000});
    db.emps.insert({"name": "王五", "age": 26, "sex": "", "job": "MANAGER", "salary": 6000});
    db.emps.insert({"name": "赵六", "age": 32, "sex": "", "job": "MANAGER", "salary": 7000});
    db.emps.insert({"name": "孙七", "age": 31, "sex": "", "job": "CLERK", "salary": 2000});
    db.emps.insert({"name": "王八", "age": 35, "sex": "", "job": "PRESIDENT", "salary": 9000}); 

    范例:按照职位分组,取得每个职位的人名 

    第一步:编写分组的定义(即Map函数):

        var jobMapFun = function(){
    
          emit(this.job, this.name);   //emit()函数表示每行数据按照job分组,取出name
    
        }; 

    分析:

    • Map函数调用emit(key, value),遍历emps中所有的记录,将key与value传递给Reduce函数进行处理
    • Map函数必须调用emit(key, value)返回的键值对
    • emit()函数是按数据的分组走,比如第一组:{key : "CLERK", values : [姓名, 姓名,...]}

    第二步:编写 reduce 操作: 

        var jobReduceFun = function(key, values){
    
          return {"job": key, "names": values};
    
        }  

    分析:reduce统计函数,reduce函数的任务是将key-values变为key-value,也就是把values数组变为一个单一的值value。

    第三步:进行操作的整合:

    db.runCommand({
        "mapreduce": "emps",
        "map": jobMapFun,
        "reduce": jobReduceFun,
        "out": "t_job_emp"
    });

    分析:out:统计结果存放集合(不指定则使用临时集合,在客户端断开后自动删除)

    执行后所有结果都保存在"t_job_emp"集合里面。

    或者将上面第三步换成如下第三步和第四步

    第三步:针对MapReduce处理完成的数据实际上也可以执行一个最后的处理

    var jobFinalizeFun = function(key, values){
        if(key == "PRESIDENT"){
            return {"job": key, "names": values, "info": "公司的老大"};
        }
        return {"job": key, "names": values};
    } 

    第四步:进行操作的整合

    db.runCommand({
        "mapreduce": "emps",
        "map": jobMapFun,
        "reduce": jobReduceFun,
        "out": "t_job_emp",
        "finalize": jobFinalizeFun
    });

    现在执行之后,所有的处理结果都保存在 “t_job_emp” 集合里面,通过如下命令查看

    db.t_job_emp.find()

    范例:统计出性别的人数、平均工资、最低工资、雇员姓名。

    var sexMapFun = function(){
      // 定义好了分组的条件,以及每个集合要取出的内容
      emit(this.sex, {"ccount" : 1, "csal" : this.salary, "cmax" : this.salary, "cmin" : this.salary, "cname" : this.name})                     
    }
    var sexReduceFun = function(key, values){
      var total = 0;  //统计
      var sum = 0;  //计算总工资
      var max = values[0].cmax;  //假设第一个数据是最高工资
      var min = values[0].cmin;  //假设第一个数据是最低工资
      for (var x in values){      // 表示循环取出里面的数据
        total += values[x].ccount;  //人数增加
        sum += values[x].csal;    //就可以循环取出所有的工资,并且累加
        if (max < values[x].cmax){  //不是最高工资
          max = values[x].cmax;
        }
        if (min > values[x].cmin){  //不是最低工资
          min = values[x].cmin;
        }
        names[x] = values[x].cname  //保存姓名
      }
      var avg = (sum / total).toFixed(2);  //toFixed(2)设置成两位小数
      //返回数据的处理结果
      return {"count" : total, "avg" : avg, "sum" : sum, "max" : max, "min" : min, "names" : names};
    }
    db.runCommand({
      "mapreduce" : "emps",
      "map" : sexMapFun,
      "reduce" : sexReduceFun,
      "out" : "t_sex_emp"
    }) 

    现在执行之后,所有的处理结果都保存在“t_sex_emp”集合里面,通过如下命令查看:

    db.t_sex_emp.find()
  • 相关阅读:
    CGO入门和OCR文字识别(非第三方API,有源码,效果好)实战
    Golang中如何正确的使用sarama包操作Kafka?
    音量强度转分贝db
    ShowDialog()弹出的窗体,关闭后,主窗体会闪烁的BUG
    小鱼提问3 static方法中可以访问某个类的私有变量吗(不通过反射的其他非正常手段)?什么情况下可以?
    “-="的陷阱
    c++ 从一个BYTE[] *filePtr 追加二进制文件
    Android解决程序切换后台被干掉,恢复状态问题
    Cookie
    dede后台搜索标签
  • 原文地址:https://www.cnblogs.com/keye/p/8004915.html
Copyright © 2020-2023  润新知