MongoDB-聚合查询

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

    语法:db.集合名称.aggergate({管道:{表达式}})

    常用的管道命令:

        -$group: 将集合中的文档分组,可以统计结果
        -$match: 过滤数据,只输出符合条件的文档
        -$project: 修改输入文档的结构,如重命名、增加、删除字段、创建计算结果
        -$sort: 将输入文档排序后输出
        -$limit: 限制聚合管道返回的文档数
        -$skip: 跳过指定数量的文档,并返回余下的文档

    常用表达式:

        -$sum: 计算总和,$sum:1 表示以一倍计数
        -$avg: 计算平均值
        -$min: 获取最小值
        -$max: 获取最大值
        -$push: 在结果文档中插入值到一个数组中

    管道命令之$group

    按照某个字段分组:

    示例1:根据姓名分组,并算出每组的个数。

db.nor_col.aggregate({$group:{_id:"$name",counter:{$sum:1}}})
结果:
    { "_id" : null, "counter" : 2 }
    { "_id" : "liu2", "counter" : 1 }
    { "_id" : "liu", "counter" : 1 }
    { "_id" : "yang", "counter" : 1 }
    { "_id" : "wang", "counter" : 3 }
    { "_id" : "孙权", "counter" : 4 }
    { "_id" : "周瑜", "counter" : 1 }
    { "_id" : "孙策", "counter" : 1 }
说明:
    _id 表示分组的依据,按照哪个字段进行分组,需要使用$name表示选择这个字段进行分组
    $sum:1 表示把每条数据作为1进行统计,统计的是该分组下面数据的条数
    counter只是个字段名称,可以随意换的,比如你换成num,那么结果就是num

    示例2: 根据姓名分组,计算出每组的个数,然后再计算出每组年龄的和

db.nor_col.aggregate({$group:{_id:"$name",counter:{$sum:1},age_sum:{$sum:"$age"}}})
结果:
    { "_id" : "liu2", "counter" : 1, "age_sum" : 21 }
    { "_id" : "liu", "counter" : 1, "age_sum" : 21 }
    { "_id" : "yang", "counter" : 1, "age_sum" : 21 }
    { "_id" : "wang", "counter" : 3, "age_sum" : 63 }
    { "_id" : "孙权", "counter" : 4, "age_sum" : 84 }
    { "_id" : "周瑜", "counter" : 1, "age_sum" : 21 }
    { "_id" : "孙策", "counter" : 1, "age_sum" : 21 }

    示例3: 根据姓名分组,根据num字段分组,然后看看每个组的名字是谁

db.nor_col.aggregate({$group:{_id:"$num",name_list:{$push:"$name"}}})
结果:
    { "_id" : 3, "name_list" : [ "liu" ] }
    { "_id" : 1, "name_list" : [ "yang" ] }
    { "_id" : 2, "name_list" : [ "wang", "wang", "wang" ] }
    { "_id" : "6", "name_list" : [ "孙权" ] }
    { "_id" : "5", "name_list" : [ "孙权" ] }
    { "_id" : "4", "name_list" : [ "孙权" ] }
    { "_id" : "3", "name_list" : [ "孙权" ] }
    { "_id" : "2", "name_list" : [ "周瑜" ] }
    { "_id" : null, "name_list" : [ "liu2" ] }
    { "_id" : "1", "name_list" : [ "孙策" ] }

    管道命令之$match:

        $match用于进行数据的过滤,是能够在聚合操作中使用的命令,和find的区别是$match操作可以把结果交给下一个管道处理,而find不行。

        示例:先找到age=21的数据,然后对这些数据分组

db.nor_col.aggregate({$match:{age:21}},{$group:{_id:"$num",name:{$push:"$name"}}})
结果:
    { "_id" : 3, "name" : [ "liu" ] }
    { "_id" : 1, "name" : [ "yang" ] }
    { "_id" : 2, "name" : [ "wang", "wang", "wang" ] }
    { "_id" : "6", "name" : [ "孙权" ] }
    { "_id" : "5", "name" : [ "孙权" ] }
    { "_id" : "4", "name" : [ "孙权" ] }
    { "_id" : "3", "name" : [ "孙权" ] }
    { "_id" : "2", "name" : [ "周瑜" ] }
    { "_id" : null, "name" : [ "liu2" ] }
    { "_id" : "1", "name" : [ "孙策" ] }

    管道命令之$project:

        $project用于修改文档的输入输出结构,例如重命名,增加,删除字段。

        示例:聚合查询之后输出name字段,不输出_id字段 

db.nor_col.aggregate({$match:{age:21}},{$group:{_id:"$num",name:{$push:"$name"}}},{$project:{_id:0,name:1}})
结果:
    { "name" : [ "liu" ] }
    { "name" : [ "yang" ] }
    { "name" : [ "wang", "wang", "wang" ] }
    { "name" : [ "孙权" ] }
    { "name" : [ "孙权" ] }
    { "name" : [ "孙权" ] }
    { "name" : [ "孙权" ] }
    { "name" : [ "周瑜" ] }
    { "name" : [ "liu2" ] }
    { "name" : [ "孙策" ] }

    管道命令之$sort:

        $sort用于将输入的文档排序后输出

        示例: 根据num值升序排序,如果num:-1 的意思是降序排序。

db.nor_col.aggregate({$sort:{num:1}})

    管道命令之$skip,$limit

        示例1:$limit的使用 

db.nor_col.aggregate({$limit:1}) 

       示例2: $skip的使用

db.nor_col.aggregate({$skip:1}) 

    管道命令之拆分"数组" $unwind

        这个用的相对较少,可以了解为就是把["a","b","c"]这样的数组拆分出来

        示例1:

db.nor_col.aggregate({$unwind:"$size"})
说明:$size是要拆解的字段

        示例2:

db.nor_col.aggregate({$unwind:{path:"$size",preserveNullAndEmptyArrays:true}})
说明:preserveNullAndEmptyArrays:true表示如果有些文档没有size这个字段,那也要展示出来一个空值 

参考:

 

posted @ 2021-03-01 15:19  寻找风口的猪  阅读(265)  评论(0编辑  收藏  举报