博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
MongoDB 聚合管道(二)(Aggregation Pipeline)
阅读量:2397 次
发布时间:2019-05-10

本文共 3721 字,大约阅读时间需要 12 分钟。

一 聚合管道的优化
   1.$sort   $skip   $limit顺序优化
     如果在执行管道聚合时,如果$sort、$skip、$limit依次出现的话,例如:
     {
 $sort: {
 age : -1 } },
     {
 $skip: 10 },
     {
 $limit: 5 }
那么实际执行的顺序为:
    {
 $sort: {
 age : -1 } },
    {
 $limit: 15 },
    {
 $skip: 10 }
   $limit会提前到$skip前面去执行。
 此时$limit = 优化前$skip+优化前$limit
 
        这样做的好处有两个:1.在经过$limit管道后,管道内的文档数量个数会“提前”减小,这样会节省内存,提高内存利用效率。2.$limit提前后,$sort紧邻$limit这样的话,当进行$sort的时候当得到前“$limit”个文档的时候就会停止。
 2$limit + $skip + $limit + $skip Sequence Optimization
    如果聚合管道内反复出现下面的聚合序列:
          {
 $limit: 100 },
          {
 $skip: 5 },
          {
 $limit: 10},
          {
 $skip: 2 }     
    
     首先进行局部优化为:可以按照上面所讲的先将第二个$limit提前:
          {
 $limit: 100 },
          {
 $limit: 15},
          {
 $skip: 5 },
          {
 $skip: 2 }
     进一步优化:两个$limit可以直接取最小值 ,两个$skip可以直接相加:
          {
 $limit: 15 },
          {
 $skip: 7 }
 3. Projection Optimization
    
     过早的使用$project投影,设置需要使用的字段,去掉不用的字段,可以大大减少内存。除此之外也可以过早使用
      我们也应该过早使用$match、$limit、$skip操作符,他们可以提前减少管道内文档数量,减少内存占用,提高聚合效率。
       除此之外,$match尽量放到聚合的第一个阶段,如果这样的话$match相当于一个按条件查询的语句,这样的话可以使用索引,加快查询效率。
二 聚合管道的限制
   
    1. 类型限制
     在管道内不能操作 Symbol, MinKey, MaxKey, DBRef, Code, CodeWScope类型的数据( 2.4版本解除了对二进制数据的限制).
     2. 结果大小限制
        管道线的输出结果不能超过BSON 文档的大小(16M),如果超出的话会产生错误.
     3. 内存限制 
      如果一个管道操作符在执行的过程中所占有的内存超过系统内存容量的10%的时候,会产生一个错误。
      当$sort和$group操作符执行的时候,整个输入都会被加载到内存中,如果这些占有内存超过系统内存的%5的时候,会将一个warning记录到日志文件。同样,所占有的内存超过系统内存容量的10%的时候,会产生一个错误。
 三 分片上使用聚合管道
     聚合管道支持在已分片的集合上进行聚合操作。当分片集合上进行聚合操作的时候,聚合管道被分为两成两个部分,分别在mongod实例和mongos上进行操作。
 四 聚合管道使用   
    
   首先下载测试数据: 并导入到数据库中。
1. 查询人口树大于一千万的州的名字
 > db.zipcode.aggregate({$group:{_id:"$state",totalPop:{$sum:"$pop"}}},
                                        {$match:{totalPop:{$gte:10*1000*1000}}},
                                        {$sort:{_id:1}})
{
     "result" : [
          {
               "_id" : "CA",
               "totalPop" : 29760021
          },
          {
               "_id" : "FL",
               "totalPop" : 12937926
          },
          {
               "_id" : "IL",
               "totalPop" : 11430602
          },
          {
               "_id" : "NY",
               "totalPop" : 17990455
          },
          {
               "_id" : "OH",
               "totalPop" : 10847115
          },
          {
               "_id" : "PA",
               "totalPop" : 11881643
          },
          {
               "_id" : "TX",
               "totalPop" : 16986510
          }
     ],
     "ok" : 1
}     
2. 计算每个州平均每个城市打人口数
> db.zipcode.aggregate({$group:{_id:{state:"$state",city:"$city"},pop:{$sum:"$pop"}}},
                                       {$group:{_id:"$_id.state",avCityPop:{$avg:"$pop"}}},
                                       {$sort:{_id:1}})
{
     "result" : [
          {
               "_id" : "AK",
               "avCityPop" : 2989.3641304347825
          },
          {
               "_id" : "AL",
               "avCityPop" : 7907.2152641878665
          },
          {
               "_id" : "AR",
               "avCityPop" : 4175.355239786856
          },
          {
               "_id" : "AZ",
               "avCityPop" : 20591.16853932584
          },
          {
               "_id" : "CA",
               "avCityPop" : 27581.113067655235
          },
          {
               "_id" : "CO",
               "avCityPop" : 9922.873493975903
          },
          {
               "_id" : "CT",
               "avCityPop" : 14674.625
          },
          {
               "_id" : "DC",
               "avCityPop" : 303450
          },
          {
               "_id" : "DE",
               "avCityPop" : 14481.91304347826
          },
          {
               "_id" : "FL",
               "avCityPop" : 26676.136082474226
          },
………………
………………
………………
          {
               "_id" : "WI",
               "avCityPop" : 7323.00748502994
          },
          {
               "_id" : "WV",
               "avCityPop" : 2759.1953846153847
          },
          {
               "_id" : "WY",
               "avCityPop" : 3359.911111111111
          }
     ],
     "ok" : 1
}  
3. 计算每个州人口最多和最少的城市名字
>db.zipcode.aggregate({$group:{_id:{state:"$state",city:"$city"},pop:{$sum:"$pop"}}},
                                      {$sort:{pop:1}},
                                      {$group:{_id:"$_id.state",biggestCity:{$last:"$_id.city"},biggestPop:{$last:"$pop"},smallestCity:{$first:"$_id.city"},smallestPop:{$first:"$pop"}}},
                                      {$project:{_id:0,state:"$_id",biggestCity:{name:"$biggestCity",pop:"$biggestPop"},smallestCity:{name:"$smallestCity",pop:"$smallestPop"}}})
{
     "result" : [ 
               "biggestCity" : {
                    "name" : "GRAND FORKS",
                    "pop" : 59527
               },
               "smallestCity" : {
                    "name" : "TROTTERS",
                    "pop" : 12
               },
               "state" : "ND"
          },
…………………
…………………
………………...
          {
               "biggestCity" : {
                    "name" : "WASHINGTON",
                    "pop" : 606879
               },
               "smallestCity" : {
                    "name" : "PENTAGON",
                    "pop" : 21
               },
               "state" : "DC"
          },
          {
               "biggestCity" : {
                    "name" : "DENVER",
                    "pop" : 451182
               },
               "smallestCity" : {
                    "name" : "CHEYENNE MTN AFB",
                    "pop" : 0
               },
               "state" : "CO"
          }
      ],
     "ok" : 1
}  
五 总结
         对于大多数的聚合操作,聚合管道可以提供很好的性能和一致的接口,使用起来比较简单, 和MapReduce一样,它也可以作用于分片集合,但是输出的结果只能保留在一个文档中,要遵守BSON Document大小限制(当前是16M)。
       管道对数据的类型和结果的大小会有一些限制,对于一些简单固定的聚集操作可以使用管道,但是对于一些复杂的、大量数据集的聚合任务还是使用MapReduce。

转载地址:http://bbfob.baihongyu.com/

你可能感兴趣的文章
心理学中的效应简单解读(r12笔记第24天)
查看>>
mysqldump简单解析
查看>>
Oracle备库无法连接主库的问题分析
查看>>
最近一周的学习计划
查看>>
MySQL备份和恢复工具图谱
查看>>
从零开始搭建Nginx和Tomcat的web集群环境
查看>>
关于技术文档
查看>>
alert日志中的一条ora警告信息的分析
查看>>
美国旧金山之行第四天
查看>>
zookeeper初探
查看>>
mysqldump与innobackupex备份过程你知多少(完结篇)
查看>>
sysbench花式踩坑之三:自增值导致的锁等待
查看>>
当心!使用mysqldump备份可能会让你欲哭无泪
查看>>
oracle 12c flex cluster专题 之 节点角色转换
查看>>
SQL优化案例-改变那些CBO无能为力的执行计划(一)
查看>>
SQL优化案例-正确的使用索引(二)
查看>>
Oracle Data Guard Feature 12cR2系列(一)
查看>>
MySQL InnoDB Update和Crash Recovery流程
查看>>
Oracle RushQL勒索病毒恢复方法
查看>>
Oracle RAC Cache Fusion 系列十:Oracle RAC Enqueues And Lock Part 1
查看>>