zoukankan      html  css  js  c++  java
  • Mongodb聚合操作之读书笔记

     Mongodb聚合操作
    读书笔记

    mongodb,两种计算聚合pipeline和mapreduce
    pipeline查询速度快于mapreduce,但MapReduce能够在多台Server上并行执行复杂的聚合逻辑。
    mongodb不允许Pipeline的单个聚合操作占用过多的系统内存,如果一个聚合操作消耗20%以上的内存,那么mongodb直接停止操作,并向客户端输出错误消息。

    Pipeline方式使用db.collection.aggregate()函数进行聚合运算,运算速度较快,操作简单。
    两条限制,单条聚合操作消耗的内存不能超过20%;聚合操作返回的结果集必须限制在16MB以内。

    $mathch过滤
    $project管道符的作用是选择字段,重命名字段,派生字段
    选择字段
    db.foo.aggregate(
    {$match:{age:{$lte:25}}}, 
    {$project:{age:1,idx:1,"_id":0}} 
    )

    重命名字段
    db.foo.aggregate(
    {$match:{age:{$lte:25}}}, 
    {$project:{age:1,"preIdx":"$idx",idx:1,"_id":0}} 
    )

    派生字段
    db.foo.aggregate(
    {$match:{age:{$lte:25}}}, 
    {$project:
         {
        age:1,
        "preIdx":{$subtract:["$idx",1]},
        idx:1,
        "_id":0}
         } 
    )

    算术操作符
    $add
    $multiply
    $divide
    $mod
    $subtract

    字符数据
    $substr:[expr,start,length] 子字符串
    $concat:[expr1,expr2,,,exprn] 连接表达式
    $toLower:expr 转小写
    $toUpper:expr 转大写

    流式运算符,只要有新doc进入,就可以对doc进行处理
    非流式运算符,必须等收到所有的文档之后,才能对文档进行处理。

    分组操作和排序操作都是非流式运算符。

    分组操作
    db.foo.aggregate(
    {$match:{age:{$lte:25}}}, 
    {$project:{age:1,"preIdx":{$subtract:["$idx",1]},idx:1,"_id":0}} ,
    {$group:{"_id":"$age",count:{$sum:1}}}
    )
    以age进行分组,统计每个分组中的doc数量

    多字段分组
    db.foo.aggregate(
    {$match:{age:{$lte:25}}}, 
    {$project:{age:1,"preIdx":{$subtract:["$idx",1]},idx:1,"_id":0}} ,
    {$group:{"_id":{age:"$age",age2:"$age"},count:{$sum:1}}}
    )

    分组聚合计算
    db.foo.aggregate(
    {$match:{age:{$lte:25}}}, 
    {$project:{age:1,"preIdx":{$subtract:["$idx",1]},idx:1,"_id":0}} ,
    {$group:
       {
        "_id":{age:"$age",age2:"$age"},
        count:{$sum:1},
        idxTotal:{$sum:"$idx"}},
        idxMax:{$max:"$idx"},
        idxFirst:{$first:"$idx"}
       }
    }
    )

    对结果进行排序,再跳过前10,再取前十个。
    db.foo.aggregate(
    {$match:{age:{$lte:25}}}, 
    {$project:{age:1,"preIdx":{$subtract:["$idx",1]},idx:1,"_id":0}} ,
    {$group:
       {
        "_id":{age:"$age",age2:"$age"},
        count:{$sum:1},
        idxTotal:{$sum:"$idx"}},
        idxMax:{$max:"$idx"},
        idxFirst:{$first:"$idx"}
       }
    },
    {$sort:{age:-1}},
    {$skip:10},
    {$limit:10}
    )

    MapReduce能够计算非常复杂,但非常慢,不适用实时数据分析。能够在多台Server上并行执行,最后由Master Server统一返回结果集。
    MapReduce方式,主要分为Map 、Shuffle、Reduce三步。
    Map,Reduce需要显式定义,shuffle由mongodb实现

    MapReduce的最佳实现,是最终结果可以加在一起的场景。

    样例,统计doc数量
    1.定义Map和Reduce
    map=function (){
    for(var key in this)
    {
      emit(key,{count:1});
    }
    }

    reduce=function (key,emits){
    total=0;
    for(var i in emits){
      total+=emits[i].count;
    }
    return {"count":total};
    }

    2.执行MapReduce
    mr=db.runCommand(
    {
    "mapreduce":"foo",
    "map":map,
    "reduce":reduce,
    out:"Count Doc"
    })

    3.查看结果
    db[mr.result].find()

    样例,统计不同age数量
    1.定义Map和Reduce
    map=function ()
    {
    emit(this.age,{count:1});
    }

    reduce= function (key,emits)
    {
    total=0;
    for(var i in emits)
    {
       total+=emits[i].count;
    }

    return {"age":key,count:total};
    }

    2.执行MapReduce
    mr=db.runCommand(
    {
    "mapreduce":"foo",
    "map":map,
    "reduce":reduce,
    out:"Count Doc"
    })

    3.查看聚合运算结果
    db[mr.result].find()

    样例,研究Reduce
    reduce= function (key,emits)
    {
    total=0;
    for(var i in emits)
    {
       total+=emits[i].count;
    }

    return {"key":key,count:total};
    }

    r1=reduce("x",[{count:1},{count:2}])
    r2=reduce("x",[{count:3},{count:5}])
    r3=reduce("x",[r1,r2])

  • 相关阅读:
    Maven介绍
    自考:计算机网络原理 2018版 李全龙 课后习题答案
    jmeter分布式部署遇到的坑
    mysql循环 insert插入多条数据
    认识Nacos.
    mysql中where子句中使用别名查询出现问题
    python之bytes和string相互转换
    什么叫线圈?什么寄存器?什么叫保持寄存器?
    Modbus-RTU详解(转载)
    python进制之间的转换函数
  • 原文地址:https://www.cnblogs.com/carrier/p/7260990.html
Copyright © 2011-2022 走看看