欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

MongoDB聚合

程序员文章站 2024-01-22 22:56:28
...

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

每个文档通过一个由多个阶段(stage)组成的管道(可以对每个阶段的管道进行分组、过滤等功能),然后经过一系列的处理输出相应的结果

MongoDB中聚合方法使用aggregate()方法,语法格式如下:
    db.集合名称.aggregate({管道:{表达式}})

MongoDB常用表达式:

表达式:用来处理输入文档并输出
语法:表达式:'$字段名'   ----> avg_age: {$avg: "$age"}

MongoDB聚合

MongoDB聚合

管道

管道在Unix和Linux中一般用于将当前命令的输出结果作为下一个命令的输入,MongoDB聚合管道将MongoDB文档在一个管道处理完毕后的结果传递给下一个管道进行处理

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

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

1. $group:将集合中的文档按照某个字段分组(group后面有几个字段结果就有几个字段)
    db.col.aggregate({$group: {_id:'$xxx', count: {$sum:1}}})
    _id用来表示分组使用的字段,格式为$字段名
    
    > db.test1.aggregate({$group:{_id:"$gender", count:{$sum:1}, avg_age:{$avg:"$age"}}})
    { "_id" : false, "count" : 2, "avg_age" : 18 }
    { "_id" : true, "count" : 5, "avg_age" : 27.8 }
    
    将所有文档分为一组:group by null
        db.col.aggregate({$group: {_id:null, count: {$sum:1}}})
    
    按照多个字段分组:
        db.col.aggregate(
            {$group:{_id:{字段名:"$字段名", 字段名:"$字段名",.....}}}
        )
    
    如果一个键对应的值为字典类型,取值时可使用$字段名.键取其内部的值


2. $project:修改输入文档的结构,如重命名(as)、增加、删除字段、创建计算结果等(投影操作)
    > db.test1.aggregate({$group:{_id:"$gender", count:{$sum:1}, avg_age:{$avg:"$age"}}})
    { "_id" : false, "count" : 2, "avg_age" : 18 }
    { "_id" : true, "count" : 5, "avg_age" : 27.8 }
    > db.test1.aggregate(
    ... {$group:{_id:"$gender", counter:{$sum:1}, avg_age:{$avg:"$age"}}},   # 分组
    ... {$project:{gender:"$_id", count:"$counter", avg_age:"$avg_age", _id:0}}  # 文档处理(投影处理)
    ... )
    { "gender" : false, "count" : 2, "avg_age" : 18 }
    { "gender" : true, "count" : 5, "avg_age" : 27.8 }
    
3. $match:用于过滤文档数据,输出符合条件的文档(使用标准查询操作)
    - match是管道命令可将结果交给下一个管道,find不可以
    > db.test1.aggregate(
    ... {$match:{age:{$gt:18}}},
    ... {$group:{_id:"$gender", counter:{$sum:1}, avg_age:{$avg:"$age"}}}
    ... )
    { "_id" : true, "counter" : 3, "avg_age" : 35 }
    
4. $sort:将输入文档排序后输出
    > db.test1.aggregate(
    ... {$group:{_id:"$gender", counter:{$sum:1}}},
    ... {$sort:{counter:-1}}
    ... )
    { "_id" : true, "counter" : 5 }
    { "_id" : false, "counter" : 2 }

5. $limit和$skip
    - $limit:限制聚合管道返回的文档数
    - $skip:跳过指定数量的文档,并返回余下的文档(先写skip,再写limit)
    > db.test1.aggregate({$limit:2})
    { "_id" : ObjectId("5e341734f059c66621de99fb"), "name" : "郭靖", "hometown" : "蒙古", "age" : 20, "gender" : true }
    { "_id" : ObjectId("5e34175df059c66621de99fc"), "name" : "黄蓉", "hometown" : "桃花岛", "age" : 18, "gender" : false }
    
    > db.test1.aggregate(
    ... {$group:{_id:"$gender", counter:{$sum:1}}},
    ... {$sort:{counter:-1}},
    ... {$skip:1},
    ... {$limit:1}
    ... )
    { "_id" : false, "counter" : 2 }
    
    
6. $unwind:将文档中的某个数组类型字段拆分为多条,每条包含数组的一个值(展开)

    ```> db.info.insert({name:"朱翔", favorite:["王者荣耀", "刺激战场", "打麻将"]})
    WriteResult({ "nInserted" : 1 })
    > db.info.aggregate(
    ... {$unwind:"$favorite"}
    ... )
    { "_id" : ObjectId("5e34e40088cc04cff3d3bf4a"), "name" : "朱翔", "favorite" : "王者荣耀" }
    { "_id" : ObjectId("5e34e40088cc04cff3d3bf4a"), "name" : "朱翔", "favorite" : "刺激战场" }
    { "_id" : ObjectId("5e34e40088cc04cff3d3bf4a"), "name" : "朱翔", "favorite" : "打麻将" }
相关标签: 数据库

上一篇: MongoDB入门教程

下一篇: MongoDB聚合