mongo聚合框架aggregate使用

1,969 阅读5分钟

mongo聚合框架aggregate使用

数据

db.emps.insert({"name":"张三","age":30,"sex":"男","job":"CLERK","salary":1000}) db.emps.insert({"name":"李四","age":28,"sex":"女","job":"CLERK","salary":2000}) db.emps.insert({"name":"王五","age":26,"sex":"男","job":"MANAGER","salary":5000}) db.emps.insert({"name":"赵六","age":32,"sex":"女","job":"MANAGER","salary":6000}) db.emps.insert({"name":"孙七","age":31,"sex":"男","job":"CLERK","salary":4000}) db.emps.insert({"name":"王八","age":35,"sex":"女","job":"PRESIDENT","salary":7000})

查询

db.emps.find()

1.png

$group

主要进行分的数据操作查询

实现 聚合查询的功能

 db.emps.aggregate([{"$group":{"_id":"$job",j_count:{"$sum":1}}}]) //每个职位的人员数量 相当于group by

// 1 { "_id": "MANAGER", "j_count": 4 }

// 2 { "_id": "PRESIDENT", "j_count": 3 }

// 3 { "_id": "CLERK", "j_count": 7 }

格式 : [] 里面 , 第一个 字段 _id 表示要操作的内容 , 之后跟着要做的事情(统计)

求出每个职位的总工资 _

db.emps.aggregate([{"$group":{"_id":"$job",job_salary:{"$sum":"$salary"}}}])

// 1 { "_id": "MANAGER", "job_salary": 22000 }

// 2 { "_id": "PRESIDENT", "job_salary": 21000 }

// 3 { "_id": "CLERK", "job_salary": 18000 }

$salary

引用每行的数据 使用 $字段名

求出每个职位的平均工资
 db.emps.aggregate([{"$group":{"_id":"$job" ,"p_count":{"$sum":1},"job_total_salary":{"$sum":"$salary"},"avg_salary":{"$avg":"$salary"}}}])

// 1 { "_id": "MANAGER", "p_count": 4, "job_total_salary": 22000, "avg_salary": 5500 }

// 2 { "_id": "PRESIDENT", "p_count": 3, "job_total_salary": 21000, "avg_salary": 7000 }

// 3 { "_id": "CLERK", "p_count": 7, "job_total_salary": 18000, "avg_salary": 2571.42857142857 }

求出每个职位最高,最低工资
db.emps.aggregate([{"$group":{"_id":"$job","max":{"$max":"$salary"} , "min":{"$min":"$salary"}}}])

// 1 { "_id": "MANAGER", "max": 6000, "min": 5000 }

// 2 { "_id": "PRESIDENT", "max": 7000, "min": 7000 }

// 3 { "_id": "CLERK", "max": 4000, "min": 1000 }

求出每个职位的工资
db.emps.aggregate([{"$group":{"_id":"$job","salary":{"$push":"$salary"}}}])

// 1 { "_id": "MANAGER", "salary": [ 5000, 6000, 5000, 6000 ] }

// 2 { "_id": "PRESIDENT", "salary": [ 7000, 7000 ] }

// 3 { "_id": "CLERK", "salary": [ 1000, 2000, 4000, 1000, 2000, 4000 ] }

$push

可以将数据变为数组保存,但是有一个问题重复数据也会进行保存

db.emps.aggregate([{"$group":{"_id":"$job","salary":{"$push":"$salary"}}}])

再插入两条数据

db.emps.insert({"name":"孙七","age":31,"sex":"男","job":"CLERK","salary":4000}) db.emps.insert({"name":"王八","age":35,"sex":"女","job":"PRESIDENT","salary":7000})

查询

2.png

查询结果

// 1 { "_id": "MANAGER", "salary": [ 5000, 6000, 5000, 6000 ] }

// 2 { "_id": "PRESIDENT", "salary": [ 7000, 7000, 7000 ] }

// 3 { "_id": "CLERK", "salary": [ 1000, 2000, 4000, 1000, 2000, 4000, 4000 ] }

解决办法是使用 $addToSet

$addToSet

mongo 中提供取消重复的数据 , $addToSet 默认显示全部数据

db.emps.aggregate([{"$group":{"_id":"$job","salary":{"$addToSet":"$salary"}}}])</pre>

// 1 { "_id": "MANAGER", "salary": [ 6000, 5000 ] }

// 2 { "_id": "PRESIDENT", "salary": [ 7000 ] }

// 3 { "_id": "CLERK", "salary": [ 4000, 2000, 1000 ] }

反着来,第一个是最后一个。 取的第一个:

db.emps.aggregate([{"$group":{"_id":"$job","salary":{"$first":"$salary"}}}])</pre>

// 1 { "_id": "MANAGER", "salary": 5000 }

// 2 { "_id": "PRESIDENT", "salary": 7000 }

// 3 { "_id": "CLERK", "salary": 1000 }

取最后一个

db.emps.aggregate([{"$group":{"_id":"$job","salary":{"$last":"$salary"}}}])

// 1 { "_id": "MANAGER", "salary": 6000 }

// 2 { "_id": "PRESIDENT", "salary": 7000 }

// 3 { "_id": "CLERK", "salary": 4000 }

所有的数据都是无序的,并且不可能支持大数据量。

$project

可以利用 来控制数据列的显示规则

普通列:{成员:1或者 true } : 表示要实现的 *id 列 {"*id":0 或者false} 表示_id 列是否显示

条件过滤 {成员:表达式} 满足表达式之后的数据可以进行显示:

只显示 name , job 列 不显示 id 列

db.emps.aggregate({"$project":{"name":1,"_id":0}})

// 1 { "name": "张三" }

// 2 { "name": "李四" }

// 3 { "name": "王五" }

// 4 { "name": "赵六" }

// 5 { "name": "孙七" }

// 6 { "name": "王八" }

// 7 { "name": "张三" }

// 8 { "name": "李四" }

// 9 { "name": "王五" }

// 10 { "name": "赵六" }

// 11 { "name": "孙七" }

// 12 { "name": "王八" }

// 13 { "name": "孙七" }

// 14 { "name": "王八" }

只有设置进去的列才能被显示出来,其他列不显示出来。

四则运算:
$add 加法
$subtract 减法
$divide 除法
$multiply 乘法
年薪计算:
 db.emps.aggregate([{"$project":{"name":1,  "_id":0,  "salary":1,  "salary":{"年薪":{"$multiply":["$salary",12]}}  }}])

// 1 { "name": "张三", "salary": { "年薪": 12000 } }

// 2 { "name": "李四", "salary": { "年薪": 24000 } }

// 3 { "name": "王五", "salary": { "年薪": 60000 } }

// 4 { "name": "赵六", "salary": { "年薪": 72000 } }

// 5 { "name": "孙七", "salary": { "年薪": 48000 } }

// 6 { "name": "王八", "salary": { "年薪": 84000 } }

// 7 { "name": "张三", "salary": { "年薪": 12000 } }

// 8 { "name": "李四", "salary": { "年薪": 24000 } }

// 9 { "name": "王五", "salary": { "年薪": 60000 } }

// 10 { "name": "赵六", "salary": { "年薪": 72000 } }

// 11 { "name": "孙七", "salary": { "年薪": 48000 } }

// 12 { "name": "王八", "salary": { "年薪": 84000 } }

// 13 { "name": "孙七", "salary": { "年薪": 48000 } }

// 14 { "name": "王八", "salary": { "年薪": 84000 } }

关系运算:

大小比较 $cmp
大于 $gt
小于 $lt
大于等于 $gte
小于等于 $lte
不等于 $ne
判断null $ifNull
等于 $eq

结果返回布尔值

月薪大于3000的数据员工

"$project":{
"_id":false,
"name":1,
"job":1,
"工资":"$salary",
"salary":{"$gt":["$salary" , 3000]}}
}
]);

// 1 { "name": "张三", "job": "CLERK", "工资": 1000, "salary": false }

// 2 { "name": "李四", "job": "CLERK", "工资": 2000, "salary": false }

// 3 { "name": "王五", "job": "MANAGER", "工资": 5000, "salary": true }

// 4 { "name": "赵六", "job": "MANAGER", "工资": 6000, "salary": true }

// 5 { "name": "孙七", "job": "CLERK", "工资": 4000, "salary": true }

// 6 { "name": "王八", "job": "PRESIDENT", "工资": 7000, "salary": true }

// 7 { "name": "张三", "job": "CLERK", "工资": 1000, "salary": false }

// 8 { "name": "李四", "job": "CLERK", "工资": 2000, "salary": false }

// 9 { "name": "王五", "job": "MANAGER", "工资": 5000, "salary": true }

// 10 { "name": "赵六", "job": "MANAGER", "工资": 6000, "salary": true }

// 11 { "name": "孙七", "job": "CLERK", "工资": 4000, "salary": true }

// 12 { "name": "王八", "job": "PRESIDENT", "工资": 7000, "salary": true }

// 13 { "name": "孙七", "job": "CLERK", "工资": 4000, "salary": true }

// 14 { "name": "王八", "job": "PRESIDENT", "工资": 7000, "salary": true }

逻辑运算

$and
$or
$not

字符串处理

连接 $concat
截取 $substr
转小写 $toLower
大小写比较 $strcsecmp
相等 $eq

查询职位是MANAGER的信息 区分小写

 db.emps.aggregate([{  "$project":{  "_id":false,  "name":1,  "job":1,  "是否":{"$eq":["$job","MANAGER"]},   "工资":"$salary",  "salary":{"$gt":["$salary" , 3000]}}  }  ]);

// 1 { "name": "张三", "job": "CLERK", "是否": false, "工资": 1000, "salary": false }

// 2 { "name": "李四", "job": "CLERK", "是否": false, "工资": 2000, "salary": false }

// 3 { "name": "王五", "job": "MANAGER", "是否": true, "工资": 5000, "salary": true }

// 4 { "name": "赵六", "job": "MANAGER", "是否": true, "工资": 6000, "salary": true }

// 5 { "name": "孙七", "job": "CLERK", "是否": false, "工资": 4000, "salary": true }

// 6 { "name": "王八", "job": "PRESIDENT", "是否": false, "工资": 7000, "salary": true }

// 7 { "name": "张三", "job": "CLERK", "是否": false, "工资": 1000, "salary": false }

// 8 { "name": "李四", "job": "CLERK", "是否": false, "工资": 2000, "salary": false }

// 9 { "name": "王五", "job": "MANAGER", "是否": true, "工资": 5000, "salary": true }

// 10 { "name": "赵六", "job": "MANAGER", "是否": true, "工资": 6000, "salary": true }

// 11 { "name": "孙七", "job": "CLERK", "是否": false, "工资": 4000, "salary": true }

// 12 { "name": "王八", "job": "PRESIDENT", "是否": false, "工资": 7000, "salary": true }

// 13 { "name": "孙七", "job": "CLERK", "是否": false, "工资": 4000, "salary": true }

// 14 { "name": "王八", "job": "PRESIDENT", "是否": false, "工资": 7000, "salary": true }

转大写

先转为大写,在比较相等

db.emps.aggregate([{  "$project":{  "_id":false,  "name":1,  "job":1,  "是否":{"$eq":["$job",{"$toUpper":"manager"}]},  "工资":"$salary"  }}  ]);

// 1 { "name": "张三", "job": "CLERK", "是否": false, "工资": 1000 }

// 2 { "name": "李四", "job": "CLERK", "是否": false, "工资": 2000 }

// 3 { "name": "王五", "job": "MANAGER", "是否": true, "工资": 5000 }

// 4 { "name": "赵六", "job": "MANAGER", "是否": true, "工资": 6000 }

// 5 { "name": "孙七", "job": "CLERK", "是否": false, "工资": 4000 }

// 6 { "name": "王八", "job": "PRESIDENT", "是否": false, "工资": 7000 }

// 7 { "name": "张三", "job": "CLERK", "是否": false, "工资": 1000 }

// 8 { "name": "李四", "job": "CLERK", "是否": false, "工资": 2000 }

// 9 { "name": "王五", "job": "MANAGER", "是否": true, "工资": 5000 }

// 10 { "name": "赵六", "job": "MANAGER", "是否": true, "工资": 6000 }

// 11 { "name": "孙七", "job": "CLERK", "是否": false, "工资": 4000 }

// 12 { "name": "王八", "job": "PRESIDENT", "是否": false, "工资": 7000 }

// 13 { "name": "孙七", "job": "CLERK", "是否": false, "工资": 4000 }

// 14 { "name": "王八", "job": "PRESIDENT", "是否": false, "工资": 7000 }

比较字符串

区分小写 用字符串比较大小 0表示返回正确

 db.emps.aggregate([{  "$project":{  "_id":false,  "name":1,  "job":1,  "是否":{"$strcasecmp":["$job","manager"]}, "工资":"$salary"  }}  ]);

// 1 { "name": "张三", "job": "CLERK", "是否": NumberInt("-1"), "工资": 1000 }

// 2 { "name": "李四", "job": "CLERK", "是否": NumberInt("-1"), "工资": 2000 }

// 3 { "name": "王五", "job": "MANAGER", "是否": NumberInt("0"), "工资": 5000 }

// 4 { "name": "赵六", "job": "MANAGER", "是否": NumberInt("0"), "工资": 6000 }

// 5 { "name": "孙七", "job": "CLERK", "是否": NumberInt("-1"), "工资": 4000 }

// 6 { "name": "王八", "job": "PRESIDENT", "是否": NumberInt("1"), "工资": 7000 }

// 7 { "name": "张三", "job": "CLERK", "是否": NumberInt("-1"), "工资": 1000 }

// 8 { "name": "李四", "job": "CLERK", "是否": NumberInt("-1"), "工资": 2000 }

// 9 { "name": "王五", "job": "MANAGER", "是否": NumberInt("0"), "工资": 5000 }

// 10 { "name": "赵六", "job": "MANAGER", "是否": NumberInt("0"), "工资": 6000 }

// 11 { "name": "孙七", "job": "CLERK", "是否": NumberInt("-1"), "工资": 4000 }

// 12 { "name": "王八", "job": "PRESIDENT", "是否": NumberInt("1"), "工资": 7000 }

// 13 { "name": "孙七", "job": "CLERK", "是否": NumberInt("-1"), "工资": 4000 }

// 14 { "name": "王八", "job": "PRESIDENT", "是否": NumberInt("1"), "工资": 7000 }

截取字符串

 db.emps.aggregate([{  "$project":{  "_id":false,  "name":1,  "job":"$job",  "job1":{"前三位":{"$substr":["$job",0,3]}},  "job2":{"$substr":["$job",0,3]}  }  }]);

// 1 { "name": "张三", "job": "CLERK", "job1": { "前三位": "CLE" }, "job2": "CLE" }

// 2 { "name": "李四", "job": "CLERK", "job1": { "前三位": "CLE" }, "job2": "CLE" }

// 3 { "name": "王五", "job": "MANAGER", "job1": { "前三位": "MAN" }, "job2": "MAN" }

// 4 { "name": "赵六", "job": "MANAGER", "job1": { "前三位": "MAN" }, "job2": "MAN" }

// 5 { "name": "孙七", "job": "CLERK", "job1": { "前三位": "CLE" }, "job2": "CLE" }

// 6 { "name": "王八", "job": "PRESIDENT", "job1": { "前三位": "PRE" }, "job2": "PRE" }

// 7 { "name": "张三", "job": "CLERK", "job1": { "前三位": "CLE" }, "job2": "CLE" }

// 8 { "name": "李四", "job": "CLERK", "job1": { "前三位": "CLE" }, "job2": "CLE" }

// 9 { "name": "王五", "job": "MANAGER", "job1": { "前三位": "MAN" }, "job2": "MAN" }

// 10 { "name": "赵六", "job": "MANAGER", "job1": { "前三位": "MAN" }, "job2": "MAN" }

// 11 { "name": "孙七", "job": "CLERK", "job1": { "前三位": "CLE" }, "job2": "CLE" }

// 12 { "name": "王八", "job": "PRESIDENT", "job1": { "前三位": "PRE" }, "job2": "PRE" }

// 13 { "name": "孙七", "job": "CLERK", "job1": { "前三位": "CLE" }, "job2": "CLE" }

// 14 { "name": "王八", "job": "PRESIDENT", "job1": { "前三位": "PRE" }, "job2": "PRE" }