zoukankan      html  css  js  c++  java
  • Mongodb的聚合和管道

    MongoDB 聚合

    MongoDB中聚合(aggregate)主要用于处理数据(诸如统计平均值,求和等),并返回计算后的数据结果。


    aggregate() 方法

    MongoDB中聚合的方法使用aggregate()。

    语法

    aggregate() 方法的基本语法格式如下所示:

    >db.COLLECTION_NAME.aggregate(AGGREGATE_OPERATION)

    注:参数AGGREGATE_OPERATION可以是一个对象(单个处理),也可以是多个对象的数组(管道处理)。

    > db.person.find()

    { "_id" : ObjectId("592ffd872108e8e79ea902b0"), "name" : "zjf", "age" : 30 }

    { "_id" : ObjectId("593011c8a92497992cdfac10"), "name" : "xhj", "age" : 30 }

    { "_id" : ObjectId("59301270a92497992cdfac11"), "name" : "zzj", "age" : 2 }

    { "_id" : ObjectId("593015fda92497992cdfac12"), "name" : "my second child", "age" : "i do not know" }

    //$group代表分组 分组的内容里的是要返回的列的名称 第一列的名称_id是不能改变的 代表以它进行分组 后面的列是汇总列 可以随便明明 $sum是汇总的方式 1是汇总的内容 可以是列如’$age’ 也可以是数值 此处 sum(1)就是count(*)的意思了。

    > db.person.aggregate({$group : {_id: '$age', count : {$sum : 1}}})

    { "_id" : "i do not know", "count" : 1 }

    { "_id" : 2, "count" : 1 }

    { "_id" : 30, "count" : 2 }

    $group : 将集合中的文档分组,可用于统计结果,$group首先将数据根据key进行分组。

          $group语法: { $group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... } }

              _id 是要进行分组的key

           $group:可以分组的数据执行如下的表达式计算:

               $sum:计算总和。

               $avg:计算平均值。

               $min:根据分组,获取集合中所有文档对应值得最小值。

               $max:根据分组,获取集合中所有文档对应值得最大值。

               $push:将指定的表达式的值添加到一个数组中。

               $addToSet:将表达式的值添加到一个集合中(无重复值)。

               $first:返回每组第一个文档,如果有排序,按照排序,如果没有按照默认的存储的顺序的第一个文档。

               $last:返回每组最后一个文档,如果有排序,按照排序,如果没有按照默认的存储的顺序的最后个文档。

    对多列进行分组:

      { "$group" : { "_id" : { "citycode":"$citycode" , "uid" : "$uid"  } , "count":{ "$sum" : 1 } } } 

    管道操作的限制:

    每个阶段管道限制为100MB的内存。如果一个节点管道超过这个极限,MongoDB将产生一个错误。为了能够在处理大型数据集,可以设置allowDiskUse为true来在聚合管道节点把数据写入临时文件。这样就可以解决100MB的内存的限制。

    这个限制可能最新版本会没有了,如果用到的时候可以去https://docs.mongodb.com/查一查官方手册。

    管道的概念

    管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的参数。

    MongoDB的聚合管道将MongoDB文档在一个管道处理完毕后将结果传递给下一个管道处理。管道操作是可以重复的。

    表达式:处理输入文档并输出。表达式是无状态的,只能用于计算当前聚合管道的文档,不能处理其它的文档。

    这里我们介绍一下聚合框架中常用的几个操作:

    • $project:修改输入文档的结构。可以用来重命名、增加或删除域,也可以用于创建计算结果以及嵌套文档。
    • $match:用于过滤数据,只输出符合条件的文档。$match使用MongoDB的标准查询操作。
    • $limit:用来限制MongoDB聚合管道返回的文档数。
    • $skip:在聚合管道中跳过指定数量的文档,并返回余下的文档。
    • $unwind:将文档中的某一个数组类型字段拆分成多条,每条包含数组中的一个值。
    • $group:将集合中的文档分组,可用于统计结果。
    • $sort:将输入文档排序后输出。
    • $geoNear:输出接近某一地理位置的有序文档。

    管道操作符实例

    1、$project实例

    db.article.aggregate(

        { $project : {

            title : 1 ,

            author : 1 ,

        }}

     );

    这样的话结果中就只还有_id,tilte和author三个字段了,默认情况下_id字段是被包含的,如果要想不包含_id话可以这样:

    db.article.aggregate(

        { $project : {

            _id : 0 ,

            title : 1 ,

            author : 1

        }});

    2.$match实例

    db.articles.aggregate( [

                            { $match : { score : { $gt : 70, $lte : 90 } } },

                            { $group: { _id: null, count: { $sum: 1 } } }

                           ] );

    $match用于获取分数大于70小于或等于90记录,然后将符合条件的记录送到下一阶段$group管道操作符进行处理。

    3.$skip实例

    db.article.aggregate(

        { $skip : 5 });

    经过$skip管道操作符处理后,前五个文档被"过滤"掉。

    性能相关:

    尽早在管道里尝试减少文档的数量和大小。

    索引只能用于$match和$sort操作。可以大大的提升性能。

    在$match和$sort之外的操作符不能使用索引。

    如果使用分片,那么$match和$project将在每个分片上执行,但是其他操作符将在主要分片上执行。(这个主要分片是什么,我没有在官方手册中找到,官方手册中只有路由,配置服务器,分片这些概念)

    在聚合管道中,一个步骤的结果将输出给下一个步骤,如果下一个步骤提前执行完毕,如limit,那么会通知上一个步骤,上一个步骤也会停止。

  • 相关阅读:
    NetStat
    Linux远程目录挂载
    Mysql服务彪高排查方式及索引的正确使用步骤
    Linux查看哪些进程占用的系统 buffer/cache 较高 (hcache,lsof)命令
    防止sql注入的最好方式
    Fortify---Detail--Sql注入
    百亿级数据处理优化
    半年的总结和思考,继续前行
    Protoc Buffer 优化传输大小的一个细节
    RPC
  • 原文地址:https://www.cnblogs.com/xiaolang8762400/p/6931217.html
Copyright © 2011-2022 走看看