聚合操作可处理数据记录并返回计算结果。聚合操作将来自多个文档的值组合在一起,并且可以对分组的数据执行各种操作以返回单个结果。官方图解如下:参考地址 https://docs.mongodb.com/manual/aggregation/
//聚合基本命令
db.orders.aggregate([
{ $match: { status: "A" } },
{ $group: { _id: "$cust_id", total: { $sum: "$amount" } } }
])
第一阶段:$match
阶段,按status
字段过滤文档,并将status
="A"
的文档传递到下一阶段。
第二阶段:$group
阶段,按cust_id
字段将文档分组,并计算每个唯一cust_id
文档中的amount
值的总和。
最基本的管道阶段提供过滤器,其操作类似于查询和修改输出文档形式的文档转换。
其他管道操作提供了用于按特定字段对文档进行分组和排序的工具,以及用于聚合包括文档数组在内的数组内容的工具。另外,管道阶段可以将运算符用于诸如计算平均值或连接字符串之类的任务。
//聚合命令基本格式:所有的阶段除$out,$merge和$geoNear阶段以外都可以在管道中出现多次。
db.collection.aggregate( [ { }, ... ] )
重点记录一下常用的几个,以后用到再补充。先给我们的数据库造一波测试数据,数据量12000,表示:用户id、年级、班级、科目、得分、时间。然后开始我们的聚合学习之路~~~
{ "_id" : ObjectId("5eeb0c2d4d057134880073b2"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "math", "score" : 50, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b3"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "chinese", "score" : 94, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b4"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "english", "score" : 7, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b5"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "science", "score" : 6, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b6"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "history", "score" : 91, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b7"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "biology", "score" : 94, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b8"), "uid" : "uid2", "grade" : 3, "class" : 9, "subject" : "math", "score" : 30, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b9"), "uid" : "uid2", "grade" : 3, "class" : 9, "subject" : "chinese", "score" : 26, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073ba"), "uid" : "uid2", "grade" : 3, "class" : 9, "subject" : "english", "score" : 28, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073bb"), "uid" : "uid2", "grade" : 3, "class" : 9, "subject" : "science", "score" : 43, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073bc"), "uid" : "uid2", "grade" : 3, "class" : 9, "subject" : "history", "score" : 48, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073bd"), "uid" : "uid2", "grade" : 3, "class" : 9, "subject" : "biology", "score" : 86, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073be"), "uid" : "uid3", "grade" : 2, "class" : 7, "subject" : "math", "score" : 68, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073bf"), "uid" : "uid3", "grade" : 2, "class" : 7, "subject" : "chinese", "score" : 7, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073c0"), "uid" : "uid3", "grade" : 2, "class" : 7, "subject" : "english", "score" : 51, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073c1"), "uid" : "uid3", "grade" : 2, "class" : 7, "subject" : "science", "score" : 88, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073c2"), "uid" : "uid3", "grade" : 2, "class" : 7, "subject" : "history", "score" : 15, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073c3"), "uid" : "uid3", "grade" : 2, "class" : 7, "subject" : "biology", "score" : 54, "createTime" : 1592462381 }
1、$match:筛选文档流,以仅允许匹配的文档未经修改地传递到下一个管道阶段。
//聚合输出匹配条件uid="uid1"的文档
db.score.aggregate([{$match:{"uid":"uid1"}}])
{ "_id" : ObjectId("5eeb0c2d4d057134880073b2"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "math", "score" : 50, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b3"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "chinese", "score" : 94, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b4"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "english", "score" : 7, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b5"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "science", "score" : 6, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b6"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "history", "score" : 91, "createTime" : 1592462381 }
{ "_id" : ObjectId("5eeb0c2d4d057134880073b7"), "uid" : "uid1", "grade" : 3, "class" : 5, "subject" : "biology", "score" : 94, "createTime" : 1592462381 }
2、$group:按指定的标识符表达式对输入文档进行分组,并为每个不同组输出一个文档。
//聚合输出uid1的score总分值
db.score.aggregate([{$match:{"uid":"uid1"}},{$group:{_id:"$uid",total:{$sum:"$score"}}}])
{ "_id" : "uid1", "total" : 342 }
//聚合输出所有用户的score总分值
db.score.aggregate([{$group:{_id:"$uid",total:{$sum:"$score"}}}])
{ "_id" : "uid1992", "total" : 188 }
{ "_id" : "uid1988", "total" : 354 }
{ "_id" : "uid1986", "total" : 329 }
{ "_id" : "uid1984", "total" : 403 }
{ "_id" : "uid1980", "total" : 199 }
{ "_id" : "uid1979", "total" : 321 }
3、$sort:通过指定的排序键对文档流重新排序。
//聚合输出所有人的总分值,并按总分降序排列
db.score.aggregate([{$group:{_id:"$uid",total:{$sum:"$score"}}},{$sort:{total:-1}}])
{ "_id" : "uid1881", "total" : 522 }
{ "_id" : "uid1187", "total" : 507 }
{ "_id" : "uid967", "total" : 497 }
{ "_id" : "uid1112", "total" : 491 }
{ "_id" : "uid758", "total" : 491 }
{ "_id" : "uid623", "total" : 488 }
{ "_id" : "uid249", "total" : 486 }
{ "_id" : "uid1646", "total" : 484 }
4、$count:返回聚合管道此阶段的文档数计数。
//先按uid分组计算总分,然后统计uid个数
db.score.aggregate([{$group:{_id:"$uid",total:{$sum:"$score"}}},{$count:"count"}])
{ "coun