zoukankan      html  css  js  c++  java
  • mongodb的常用操作(三)

    继续mongodb的学习和总结:

    11.mongodb的mapreduce功能
    mapreduce可以说是mongodb的一个很强大的功能,可以实现复杂的运算和统计,做一个简要的总结:
    假设有user集合,内容如下:
    > db.user.find()
    { "_id" : ObjectId("52ab35d281181f85326409da"), "uname" : "jiangwang", "pwd" : 123456, "age" : 111 }
    { "_id" : ObjectId("52ab35d281181f85326409db"), "uname" : "jiangwang", "pwd" : 123456, "age" : 111 }
    { "_id" : ObjectId("52ab35d281181f85326409dc"), "uname" : "jiangwang", "pwd" : 123456, "age" : 111 }
    { "_id" : ObjectId("52ab35d281181f85326409dd"), "uname" : "jiangwang", "pwd" : 123456, "age" : 111 }
    { "_id" : ObjectId("52ab35d281181f85326409de"), "uname" : "jiangwang", "pwd" : 123456, "age" : 111 }
    { "_id" : ObjectId("52ab35d281181f85326409df"), "uname" : "jiangwang", "pwd" : 123456, "age" : 111 }
    { "_id" : ObjectId("52ab35d281181f85326409e0"), "uname" : "jiangwang", "pwd" : 123456, "age" : 111 }
    { "_id" : ObjectId("52ab35d281181f85326409e1"), "uname" : "jiangwang", "pwd" : 123456, "age" : 111 }
    { "_id" : ObjectId("52ab35d281181f85326409e2"), "uname" : "jiangwang", "pwd" : 123456, "age" : 111 }
    { "_id" : ObjectId("52ab35d281181f85326409e3"), "uname" : "jiangwang", "pwd" : 123456, "age" : 111 }
    { "_id" : ObjectId("52ac600d430cfd3d522c6b30"), "uname" : "jiang", "pwd" : "hello", "age" : 24 }

    mapreduce的功能就是,通过map分组得到列表,然后通过reduce对map的列表进行计算,得到最终的结果

    mapreduce分两部分,map和reduce。

    map函数的定义为Map(k1,v1) → list(k2,v2)

    reduce函数的定义Reduce(k2, list(v2)) → list(v3)

    map运算后得到一个列表,reduce将列表转换为另外一种形式的列表

    MapReduce 的操作:
    db.runCommand(
    {
    mapreduce : <collection>,
    map : <mapfunction>,
    reduce : <reducefunction>
    [, query : <query filter object>]
    [, sort : <sorts the input objects using this key. Useful for optimization, like sorting by the emit key for fewer reduces>]
    [, limit : <number of objects to return from collection>]
    [, out : <see output options below>]
    [, keeptemp: <true|false>]
    [, finalize : <finalizefunction>]
    [, scope : <object where fields go into javascript global scope >]
    [, verbose : true]
    }
    );
    参数说明:
     mapreduce: 要操作的目标集合名字。
     map: 映射函数 (生成键值对序列,作为 reduce 函数参数)。
     reduce: 统计函数。
     query: 目标记录过滤。
     sort: 目标记录排序。
     limit: 限制目标记录数量。
     out: 统计结果存放集合 (不指定则使用临时集合,在客户端断开后自动删除)。
     keeptemp: 是否保留临时集合。
     finalize: 最终处理函数 (对 reduce 返回结果进行最终整理后存入结果集合)。
     scope: 向 map、reduce、finalize 导入外部变量。
     verbose: 显示详细的时间统计信息。
    []中为可选参数
    例如,需要计算出user表中的相同姓名的年龄的总和,并且根据姓名和年领分组:
    db.runCommand({
    mapreduce:"user",
    map:function(){
    emit({key0:this.uname,key1:this.age},this.age);
    },
    reduce:function(key,values){
    var total = 0;
    for(var i = 0; i < values.length; i++){
    total += values[i];
    }
    return total;
    },
    out:"user_groupbyname"
    });
    将分组结果输出到user_groupbyname集合中,db.user_groupbyname.find()结果如下:
    { "_id" : { "key0" : "hello" , "key1" : 24 }, "value" : 24 }
    { "_id" : { "key0" : "jiang" , "key1" : 24 }, "value" : 24 }
    { "_id" : { "key0" : "jiangwang", "key1" : 111 }, "value" : 1110 }

    当然为了简洁,js可以用变量存储函数:
    var m = function(){
    emit({key0:this.uname,key1:this.age},this.age);
    };

    var r = function(key,values){
    var total = 0;
    for(var i = 0; i < values.length; i++){
    total += values[i];
    }
    return total;
    };

    db.runCommand({
    mapreduce:"user",
    map:m,
    reduce:r,
    out:"user_groupbyname"
    });

    在第10部分学习过mongodb的存储过程,其实就是函数,那么这里就可以将函数写到system.js集合中,通过db.eval()调用
    db.system.js.save({_id:'m',value:function(){
    emit({key0:this.uname,key1:this.age},this.age);
    }});
    db.system.js.save({_id:'r',value:function(key,values){
    var total = 0;
    for(var i = 0; i < values.length; i++){
    total += values[i];
    }
    return total;
    }});
    调用方式如下:
    db.runCommand({
    mapreduce:"user",
    map:db.eval("m"),
    reduce:db.eval("r"),
    out:"user_groupbyname"
    });

    以上三种方式写mapreduce结果都一样.

    另外,在使用map和reduce根据具体的需求,可以灵活改变这两个函数,实现不同的功能。

    例如需要统计名字相同的人的年龄的平均值,那么reduce函数改成求平均值:
    var r = function(key,values){
    var total = 0;
    for(var i = 0; i < values.length; i++){
    total += values[i];
    }
    if(values.length != 0){
    return total/values.length;
    }
    else{
    return 0;
    }
    };

  • 相关阅读:
    Jmeter——关联与正则
    Jmeter图形插件扩展
    Jmeter——检查点
    Jmeter——集合点
    OpenGL帧缓存对象(FBO:Frame Buffer Object)(转载)
    unicode 和 utf8
    管理node的版本
    pyqt5 开发环境
    cmake
    一些可能常用的工具函数
  • 原文地址:https://www.cnblogs.com/jiangwang2013/p/3669848.html
Copyright © 2011-2022 走看看