数据库MongoDB-聚合查询

2021-02-04 10:59:41 浏览数 (1)

MongoDB 聚合查询

在MongoDB中我们可以通过aggregate()函数来完成一些聚合查询,aggregate()函数主要用于处理诸如统计,平均值,求和等,并返回计算后的数据结果。

语法格式:

代码语言:javascript复制
db.COLLECTION_NAME.aggregate([{$group:{_id:"$分组键名","$分组键名",.....,别名:{聚合运算:"$运算列"}}},{条件筛选:{键名:{运算条件:运算值}}}])

常见的mongo的聚合操作和mysql的查询做类比

求和 - $sum

查询dev集合中一共有多少个文档。

相当于sql语句:SELECT count(*) AS count FROM c1

代码语言:javascript复制
db.c1.aggregate([{$group:{_id:null,count:{$sum:1}}}])

$group:分组,代表聚合的分组条件

_id:分组的字段,是必须有的。相当于SQL分组语法group by column_name中的column_name部分。如果根据某字段的值分组,则定义为_id:’$字段名’。如果没有分组属性取值为null

count:返回结果字段名。可以自定义,类似SQL中的字段别名。

$sum:如果取值为1表示总条数,相当于每个document中都多个count属性,count取值为1,累加和就是总条数。如果 s u m 取 值 是 ‘ sum取值是‘ sum取值是‘field名’(要注意有单引号或双引号),表示对该field求累加和

取总和

sum取值必须是字符串类型,有双引号。age是属性名,前面必须有

代码语言:javascript复制
db.c1.aggregate([{$group:{_id:null,totalAge:{$sum:"$age"}}}]);
分组后取总和

_id取值也是字符串类型,里面必须是属性名前面加上$

代码语言:javascript复制
db.c1.aggregate([{$group:{_id:"$name",totalAge:{$sum:"$age"}}}]);
条件筛选 - $match

match和group同级操作符,需要写在两个条件中的。

写在$group前面

match写在group前面表示先过滤条件,在分组。

先查询出age大于等于5的文档对象,在按照name属性进行分组,计算age列总和

代码语言:javascript复制
db.c1.aggregate([{$match:{age:{$gte:5}}},{$group:{_id:"$name",totalAge:{$sum:"$age"}}}]);

写在$group后面

match写在group后面表示分组后在设置条件。

分组后结果集只有_id和totalAge两个属性,所以在$match中只能对这个属性进行操作。

代码语言:javascript复制
db.c1.aggregate([{$group:{_id:"$name",totalAge:{$sum:"$age"}}},{$match:{totalAge:{$gte:5}}}]);
最大值 - $max

$max可以计算最大值。

代码语言:javascript复制
db.c1.aggregate([{$group:{_id:"$name",maxAge:{$max:"$age"}}}]);
最小值 - $min

$min可以计算最小值

代码语言:javascript复制
db.c1.aggregate([{$group:{_id:"$name",minAge:{$min:"$age"}}}]);
平均值 - $avg

计算出不同姓名的平均年龄

代码语言:javascript复制
db.c1.aggregate([{$group:{_id:"$name",avgAge:{$avg:"$age"}}}]);
统计结果返回数组 - $push

分组后按照分组数组进行合并,如果希望看到某个列合并之前的所有数据可以使用$push,把分组后同一组的所有值放到一个数组中

按照name进行分组,分组后把age的数据都放入到名称为allAge的数组中

代码语言:javascript复制
db.c1.aggregate([{$group:{_id:"$name",allAge:{$push:"$age"}}}])

运行结果

数组字段拆分 - $unwind

$unwind会把数组列进行拆分,原来的document会根据数组属性值个数分为多个document。如果这个数组属性为空,对应document将不被显示(因为document没有数组属性)

正常数据:只有name为abc的hobby有数组类型值,且长度为3

执行下面命令后的效果

代码语言:javascript复制
db.c1.aggregate([{$unwind:"$hobby"}]);

0 人点赞