MongoDB二个主要的操作:一个是查询,另一个是统计。对于查询而言,主要是find()方法,再配合Filters组合多个查询条件

对于统计而言,则主要是aggregate操作,比如 group、sum、avg、project、match……

aggregate可以将上述操作组织成 pipeline 形式,依次经过各种操作处理。

本文是MongoDB University M101的课程笔记,主要记录:MongoDB aggregate的一些常用操作。

参考资料:sql to aggregation mapping chart

①project

它是个1:1的操作,即一个Document输入给project处理,输出一个新的Document。它主要对Key进行处理(大小写转换、删除原来Document某些Key……)

比如原Document如下:

{
"city" : "ACMAR",
"loc" : [
-86.51557,
33.584132
],
"pop" : 6055,
"state" : "AL",
"_id" : "35004"
}

想把它变成:

{
"city" : "acmar",
"pop" : 6055,
"state" : "AL",
"zip" : "35004"
}

使用:project操作符进行处理:

db.zips.aggregate([
{$project:{_id:0, city:{$toLower:"$city"}, pop:1, state:1, zip:"$_id"}}
])
_id:0  去掉原Document中的_id字段;city:{$ toLower:"$city"}   对原Document中的 "$city" 的值全部转换成小写,赋给新city字段

pop:1  state:1  表示将原Document中的 pop 字段、state 字段 放到新Document中

zip:"$_id" 将原Document中的 '_id'字段值  赋值给 新的 "zip" 字段  

②group avg,根据分组求平均值。比如某个Document格式如下:对 state字段进行分组,求每个state的人口(pop)的平均值

{
"city" : "FISHERS ISLAND",
"loc" : [
-72.017834,
41.263934
],
"pop" : 329,
"state" : "NY",
"_id" : "06390"
}
db.zips.aggregate([
{"$group":{"_id":"$state", "average_pop":{"$avg":"$pop"}}}
])

$group表示分组操作,执行该操作后会生成一个新Document。

_id:$state 表示对 $state 字段进行分组,生成的新Document的 _id 为 state的值
"$avg":"$pop" 表示对原Document中的 “pop”字段按 $state 分组求平均值。得到的平均值为 "average_pop"字段的值。

最终的结果如下:

{ "_id" : "NY", "average_pop" : 9705.34 }
{ "_id" : "CT", "average_pop" : 13226.48 }
{ "_id" : "CA", "average_pop" : 19067.72 }
{ "_id" : "NJ", "average_pop" : 16949.9 }

③match

Document示例如下:想要过滤人口字段(pop)大于100 000 的所有记录。

{
"city" : "ACMAR",
"loc" : [
-86.51557,
33.584132
],
"pop" : 6055,
"state" : "AL",
"_id" : "35004"
}
db.zips.aggregate([
{$match:{
pop:{$gt:100000}
}
}
])

$match表示对 Document进行过滤

pop:{$gt:100000} 表示根据 pop 字段过滤,过滤的条件为 pop 的值大于100000

④sort

Document示例如下,现在需要对 state 和 city 这两个字段进行升序排序。

{
"city" : "ACMAR",
"loc" : [
-86.51557,
33.584132
],
"pop" : 6055,
"state" : "AL",
"_id" : "35004"
}
db.zips.aggregate( [ { $sort:{state:1, city:1} } ] )

返回结果如下:

{ "_id" : "95915", "city" : "BELDEN", "loc" : [ -121.325924, 39.921746 ], "pop" : 32, "state" : "CA" }
{ "_id" : "90706", "city" : "BELLFLOWER", "loc" : [ -118.126527, 33.886676 ], "pop" : 61650, "state" : "CA" }
{ "_id" : "93430", "city" : "CAYUCOS", "loc" : [ -120.890791, 35.444606 ], "pop" : 3384, "state" : "CA" }
{ "_id" : "96107", "city" : "COLEVILLE", "loc" : [ -119.482784, 38.502903 ], "pop" : 1370, "state" : "CA" }

⑤group、sort、first

Document示例如下,现在要寻找,每个州(state)下的 每个城市(city)人口的最大值。

{ "_id" : "07840", "city" : "HACKETTSTOWN", "loc" : [ -74.834315, 40.852891 ], "pop" : 23440, "state" : "NJ" }
{ "_id" : "93254", "city" : "NEW CUYAMA", "loc" : [ -119.823806, 34.996709 ], "pop" : 80, "state" : "CA" }
{ "_id" : "92278", "city" : "TWENTYNINE PALMS", "loc" : [ -116.06041, 34.237969 ], "pop" : 11412, "state" : "CA" }
{ "_id" : "08536", "city" : "PLAINSBORO", "loc" : [ -74.568836, 40.332432 ], "pop" : 13008, "state" : "NJ" }
{ "_id" : "06117", "city" : "W HARTFORD", "loc" : [ -72.745689, 41.790021 ], "pop" : 14774, "state" : "CT" }
{ "_id" : "06071", "city" : "SOMERS", "loc" : [ -72.458266, 41.997813 ], "pop" : 9685, "state" : "CT" }
{ "_id" : "92070", "city" : "SANTA YSABEL", "loc" : [ -116.69635, 33.147579 ], "pop" : 1263, "state" : "CA" }
{ "_id" : "91941", "city" : "LA MESA", "loc" : [ -117.011541, 32.760431 ], "pop" : 42536, "state" : "CA" }
{ "_id" : "06705", "city" : "WATERBURY", "loc" : [ -72.996268, 41.550328 ], "pop" : 25128, "state" : "CT" }
{ "_id" : "07750", "city" : "MONMOUTH BEACH", "loc" : [ -73.98089, 40.333032 ], "pop" : 3329, "state" : "NJ" }
{ "_id" : "06095", "city" : "WINDSOR", "loc" : [ -72.663893, 41.856122 ], "pop" : 27815, "state" : "CT" }
{ "_id" : "06702", "city" : "WATERBURY", "loc" : [ -73.038545, 41.556568 ], "pop" : 4522, "state" : "CT" }
{ "_id" : "13833", "city" : "SANITARIA SPRING", "loc" : [ -75.790978, 42.195735 ], "pop" : 4777, "state" : "NY" }
{ "_id" : "95363", "city" : "PATTERSON", "loc" : [ -121.140732, 37.490592 ], "pop" : 13437, "state" : "CA" }

第一步:统计每个州下每个城市的人口总和:

db.zips.aggregate( [ 
{ $group:
{_id:{state:"$state",city:"$city"},
population:{$sum:"$pop"}}
}
] )

得到如下Document:(注意Document的 _id 变化)

{ "_id" : { "state" : "NJ", "city" : "ISLAND HEIGHTS" }, "population" : 1470 }
{ "_id" : { "state" : "NY", "city" : "REDWOOD" }, "population" : 1735 }
{ "_id" : { "state" : "CT", "city" : "TAFTVILLE" }, "population" : 2538 }
{ "_id" : { "state" : "CT", "city" : "ELLINGTON" }, "population" : 9070 }
{ "_id" : { "state" : "CT", "city" : "STORRS MANSFIELD" }, "population" : 16117 }
{ "_id" : { "state" : "NJ", "city" : "MERCHANTVILLE" }, "population" : 22294 }
{ "_id" : { "state" : "NJ", "city" : "STRATHMERE" }, "population" : 163 }
{ "_id" : { "state" : "CA", "city" : "LA JOLLA" }, "population" : 40399 }
{ "_id" : { "state" : "NY", "city" : "HURLEYVILLE" }, "population" : 3303 }
{ "_id" : { "state" : "NJ", "city" : "NORTH BRANCH" }, "population" : 34212 }
{ "_id" : { "state" : "NJ", "city" : "WEEHAWKEN" }, "population" : 69646 }
{ "_id" : { "state" : "NJ", "city" : "MANALAPAN" }, "population" : 28928 }
{ "_id" : { "state" : "NY", "city" : "NEW YORK" }, "population" : 8190 }
{ "_id" : { "state" : "NY", "city" : "DEWITTVILLE" }, "population" : 1159 }
{ "_id" : { "state" : "NY", "city" : "QUEENSBURY" }, "population" : 15023 }
....
....

按state 对人口进行排序

db.zips.aggregate( [ 
{ $group:{_id:{state:"$state",city:"$city"}, population:{$sum:"$pop"}} },
{$sort:{"_id.state":1, "population":-1}}
] )

得到如下Document:

{ "_id" : { "state" : "CA", "city" : "LOS ANGELES" }, "population" : 104702 }
{ "_id" : { "state" : "CA", "city" : "LA MESA" }, "population" : 66480 }
{ "_id" : { "state" : "CA", "city" : "SHORE ACRES" }, "population" : 64053 }
{ "_id" : { "state" : "CA", "city" : "BELLFLOWER" }, "population" : 61650 }
{ "_id" : { "state" : "CA", "city" : "VISALIA" }, "population" : 51620 }
{ "_id" : { "state" : "CA", "city" : "SAN DIEGO" }, "population" : 45487 }
{ "_id" : { "state" : "CA", "city" : "GOLD RIVER" }, "population" : 42461 }
....
....

然后,再对 state 进行 group by,使用 $first 取第一条记录:就是这个州下 的人口最大的城市(city).

first 一般和 group使用:$group得到一组Document后,使用 $first 获取该组Documents中的第一个Document。

 db.zips.aggregate([ 
{
$group:{_id:{state:"$state",city:"$city"},
population:{$sum:"$pop"}
}
},
{$sort:{"$_id.state":1, "population":-1}},
{$group:{_id:"_id.state",
city:{$first:"$_id.city"},
population:{$first:"$population"}
}
}
])

得到:

{ "_id" : "NJ", "city" : "JERSEY CITY", "population" : 100756 }
{ "_id" : "NY", "city" : "FLUSHING", "population" : 51947 }
{ "_id" : "CT", "city" : "BRISTOL", "population" : 60670 }
{ "_id" : "CA", "city" : "LOS ANGELES", "population" : 104702 }

最后再对 _id 排序

 db.zips.aggregate( [ 
{ $group:{_id:{state:"$state",city:"$city"},
population:{$sum:"$pop"}} },
{$sort:{"_id.state":1, "population":-1}},
{$group:{_id:"$_id.state",city:{$first:"$_id.city"},population:{$first:"$population"}}},
{$sort:{"_id":1}}
] )

得到:

{ "_id" : "CA", "city" : "LOS ANGELES", "population" : 104702 }
{ "_id" : "CT", "city" : "BRISTOL", "population" : 60670 }
{ "_id" : "NJ", "city" : "JERSEY CITY", "population" : 100756 }
{ "_id" : "NY", "city" : "FLUSHING", "population" : 51947 }

Mongodb aggregation 基本操作示例的更多相关文章

  1. mongodb的基本操作与插入文档(document)

    一.mongodb的基本操作: 1.查看mongodb当前所有的databases : show dbs 2.选择数据库(database) : use databaseName(该数据库不存在则会自 ...

  2. Node.js与MongoDB的基本连接示例

    Node.js与MongoDB的基本连接示例 前提 已经安装了node.js和MongoDB,本文使用的node.js是v0.12.0,MongoDB是3.0.0. 初始化数据 启动MongoDB服务 ...

  3. 【网络爬虫入门05】分布式文件存储数据库MongoDB的基本操作与爬虫应用

    [网络爬虫入门05]分布式文件存储数据库MongoDB的基本操作与爬虫应用 广东职业技术学院  欧浩源 1.引言 网络爬虫往往需要将大量的数据存储到数据库中,常用的有MySQL.MongoDB和Red ...

  4. MongoDB之基本操作与日常维护

    MongoDB基本操作 MongoDB的基本操作主要是对数据库.集合.文档的操作,包括创建数据库.删除数据库.插入文档.更改文档.删除文档.和查询文档. 操作 描述 show dbs 查看当前实例下的 ...

  5. 孤荷凌寒自学python第六十六天学习mongoDB的基本操作并进行简单封装5

    孤荷凌寒自学python第六十六天学习mongoDB的基本操作并进行简单封装5并学习权限设置 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第十二天. 今天继续学习mongo ...

  6. 孤荷凌寒自学python第六十五天学习mongoDB的基本操作并进行简单封装4

    孤荷凌寒自学python第六十五天学习mongoDB的基本操作并进行简单封装4 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第十一天. 今天继续学习mongoDB的简单操作 ...

  7. 孤荷凌寒自学python第六十四天学习mongoDB的基本操作并进行简单封装3

    孤荷凌寒自学python第六十四天学习mongoDB的基本操作并进行简单封装3 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第十天. 今天继续学习mongoDB的简单操作, ...

  8. 孤荷凌寒自学python第六十三天学习mongoDB的基本操作并进行简单封装2

    孤荷凌寒自学python第六十三天学习mongoDB的基本操作并进行简单封装2 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第九天. 今天继续学习mongoDB的简单操作, ...

  9. 孤荷凌寒自学python第六十二天学习mongoDB的基本操作并进行简单封装1

    孤荷凌寒自学python第六十二天学习mongoDB的基本操作并进行简单封装1 (完整学习过程屏幕记录视频地址在文末) 今天是学习mongoDB数据库的第八天. 今天开始学习mongoDB的简单操作, ...

随机推荐

  1. ⌈洛谷1505⌋⌈BZOJ2157⌋⌈国家集训队⌋旅游【树链剖分】

    题目链接 [洛谷] [BZOJ] 题目描述 Ray 乐忠于旅游,这次他来到了T 城.T 城是一个水上城市,一共有 N 个景点,有些景点之间会用一座桥连接.为了方便游客到达每个景点但又为了节约成本,T ...

  2. bzoj4337树的同构

    树是一种很常见的数据结构. 我们把N个点,N-1条边的连通无向图称为树. 若将某个点作为根,从根开始遍历,则其它的点都有一个前驱,这个树就成为有根树. 对于两个树T1和T2,如果能够把树T1的所有点重 ...

  3. 数据库设计E-R图

    项目数据库的设计主要划分为以下6个阶段,本篇主要着重来介绍概念设计阶段 A.系统需求分析阶段B.概念结构设计阶段C.逻辑结构设计阶段D.物理结构设计阶段E.数据库实施阶段F.数据库运行与维护阶段 E- ...

  4. LinkedList(JDK1.8)源码分析

    双向循环链表 双向循环链表和双向链表的不同在于,第一个节点的pre指向最后一个节点,最后一个节点的next指向第一个节点,也形成一个"环".而LinkedList就是基于双向循环链 ...

  5. socket,tcp,http三者之间的区别和原理

    http.TCP/IP协议与socket之间的区别下面的图表试图显示不同的TCP/IP和其他的协议在最初OSI模型中的位置: 7 应用层 例如HTTP.SMTP.SNMP.FTP.Telnet.SIP ...

  6. js 获取对象属性个数

    js 获取对象属性个数 方法一: var attributeCount = function(obj) { var count = 0; for(var i in obj) { if(obj.hasO ...

  7. LOJ#2306 蔬菜

    补充一个题意不太清楚的地方:蔬菜坏掉是假设蔬菜都有标号,那么特定标号的蔬菜就会在特定时间坏掉.如果你及时卖了它们,那么那一天就不会有新的蔬菜坏掉. 结论1:如果我们知道了k天的答案,那么我们直接扔掉若 ...

  8. vue2.0获取自定义属性的值

    最近在项目中使用了vue.js.在爬坑的路上遇到了很多问题.这里都会给记录下来,今天要说的是怎么获取自定义属性的值. HTML <!DOCTYPE html> <html> & ...

  9. Session 常见操作

    对于敏感.重要的信息,建议要存储在服务器端(Session是存储在服务器端的),不能存储在浏览器中,如用户名.余额.等级.验证码等信息 Session依赖于Cookie session数据的获取 se ...

  10. (转)c++ 回调函数

    https://www.cnblogs.com/chenyuming507950417/archive/2012/01/02/2310114.html 今天讨论下C/C++中的回调函数. 在理解“回调 ...