做一个mongodb关于其聚合函数的使用做一个总结,后续也会不断完善
1.插入一个班级表
// 班级
db.class.insert([{name:'三年级一班',num:52,teacher:'张三'},
{name:'三年级二班',num:49,teacher:'李四'},
{name:'三年级三班',num:50,teacher:'张三'},
{name:'三年级四班',num:51,teacher:'王二'},
{name:'三年级五班',num:52,teacher:'王一'}
])
2.学生成绩表
// 学生成绩表
db.grade.insert([{name:'学生A',classId:ObjectId("5d0b352cdf5e0f598fc8aba0"),yuwen:80,shuxue:58,yinyu:85},
{name:'学生B',classId:ObjectId("5d0b352cdf5e0f598fc8aba0"),yuwen:70,shuxue:99,yinyu:92},
{name:'学生C',classId:ObjectId("5d0b352cdf5e0f598fc8aba1"),yuwen:90,shuxue:95,yinyu:94},
{name:'学生D',classId:ObjectId("5d0b352cdf5e0f598fc8aba1"),yuwen:50,shuxue:85,yinyu:45},
{name:'学生E',classId:ObjectId("5d0b352cdf5e0f598fc8aba4"),yuwen:68,shuxue:75,yinyu:72}
]);
3.分不同步骤加深对聚合函数的使用:
db.class.aggregate([
{
$lookup:{ //关联集合
from:'grade', // 关联集合
localField:'_id',// 关联集合的字段
foreignField:'classId',// 被关联集合字段
as:'class_grade' //关联后输出的集合,(临时集合),类似于关系型数据库关联后生成字段的别名
}
}])
当如上述进行查询时,返回的结果如下
可以看到最后的class_grade是一个数组,其json格式如下,这里可以看出直接使用这样的关联,就如同关系型数据库的left join。
/* 1 */
{
"_id" : ObjectId("5d0b352cdf5e0f598fc8aba0"),
"name" : "三年级一班",
"num" : 52,
"teacher" : "张三",
"class_grade" : [{
"_id" : ObjectId("5d0b3683df5e0f598fc8aba5"),
"name" : "学生A",
"classId" : ObjectId("5d0b352cdf5e0f598fc8aba0"),
"yuwen" : 80,
"shuxue" : 58,
"yinyu" : 85
}, {
"_id" : ObjectId("5d0b3683df5e0f598fc8aba6"),
"name" : "学生B",
"classId" : ObjectId("5d0b352cdf5e0f598fc8aba0"),
"yuwen" : 70,
"shuxue" : 99,
"yinyu" : 92
}]
}
/* 2 */
{
"_id" : ObjectId("5d0b352cdf5e0f598fc8aba1"),
"name" : "三年级二班",
"num" : 49,
"teacher" : "李四",
"class_grade" : [{
"_id" : ObjectId("5d0b3683df5e0f598fc8aba7"),
"name" : "学生C",
"classId" : ObjectId("5d0b352cdf5e0f598fc8aba1"),
"yuwen" : 90,
"shuxue" : 95,
"yinyu" : 94
}, {
"_id" : ObjectId("5d0b3683df5e0f598fc8aba8"),
"name" : "学生D",
"classId" : ObjectId("5d0b352cdf5e0f598fc8aba1"),
"yuwen" : 50,
"shuxue" : 85,
"yinyu" : 45
}]
}
/* 3 */
{
"_id" : ObjectId("5d0b352cdf5e0f598fc8aba2"),
"name" : "三年级三班",
"num" : 50,
"teacher" : "张三",
"class_grade" : []
}
/* 4 */
{
"_id" : ObjectId("5d0b352cdf5e0f598fc8aba3"),
"name" : "三年级四班",
"num" : 51,
"teacher" : "王二",
"class_grade" : []
}
/* 5 */
{
"_id" : ObjectId("5d0b352cdf5e0f598fc8aba4"),
"name" : "三年级五班",
"num" : 52,
"teacher" : "王一",
"class_grade" : [{
"_id" : ObjectId("5d0b3683df5e0f598fc8aba9"),
"name" : "学生E",
"classId" : ObjectId("5d0b352cdf5e0f598fc8aba4"),
"yuwen" : 68,
"shuxue" : 75,
"yinyu" : 72
}]
}
4.去掉里面的空字符串。有两种办法
1)使用$match加入判断返回数据不为空数组的条件,这样查询出来的结果class_grade
db.class.aggregate([
{
$lookup:{ //关联集合
from:'grade', // 关联集合
localField:'_id',// 关联集合的字段
foreignField:'classId',// 被关联集合字段
as:'class_grade' //关联后输出的集合,(临时集合),类似于关系型数据库关联后生成字段的别名
}
},
{
$match:{ //条件筛选集合,可以筛选聚合之后的集合,也可以筛选原集合中的元素
class_grade:{$ne:[]}
}
}
])
2)使用$unwind拆分子数组,这样返回的class_grade,就不再是一个数组,而是一个新的文档,可以自行试验返回结果
db.class.aggregate([
{
$lookup:{ //关联集合
from:'grade', // 关联集合
localField:'_id',// 关联集合的字段
foreignField:'classId',// 被关联集合字段
as:'class_grade' //关联后输出的集合,(临时集合),类似于关系型数据库关联后生成字段的别名
}
},
{
$unwind:{ //拆分子数组,一条一条进行显示
path:'$class_grade',
preserveNullAndEmptyArrays:true // 去掉空数组
}
}])
5.$match的使用,在此可以如下所示加入 shuxue>60 和yuwen>60的条件,也可以灵活的加入各种条件。和mongodb直接查询一样
db.class.aggregate([
{
$lookup:{ //关联集合
from:'grade', // 关联集合
localField:'_id',// 关联集合的字段
foreignField:'classId',// 被关联集合字段
as:'class_grade' //关联后输出的集合,(临时集合),类似于关系型数据库关联后生成字段的别名
}
},
{
$unwind:{ //拆分子数组,一条一条进行显示
path:'$class_grade',
preserveNullAndEmptyArrays:true // 去掉空数组
}
}]),
{
$match:{ //条件筛选集合,可以筛选聚合之后的集合,也可以筛选原集合中的元素
"class_grade.shuxue":{$gt:60},"class_grade.yuwen":{$gt:60},num:{$gt:50}
}
}])
6.$group和$sort的使用,直接看如下代码
db.class.aggregate([
{
$lookup:{ //关联集合
from:'grade', // 关联集合
localField:'_id',// 关联集合的字段
foreignField:'classId',// 被关联集合字段
as:'class_grade' //关联后输出的集合,(临时集合),类似于关系型数据库关联后生成字段的别名
}
},
{
$unwind:{ //拆分子数组,一条一条进行显示
path:'$class_grade',
preserveNullAndEmptyArrays:true // 去掉空数组
}
}]),
{
$match:{ //条件筛选集合,可以筛选聚合之后的集合,也可以筛选原集合中的元素
"class_grade.shuxue":{$gt:60},"class_grade.yuwen":{$gt:60},num:{$gt:50}
}
},
{
$group:{ // 进行分组,下面是希望显示的字段
_id:'$_id',
name:{$first:'$class_grade.name'},
fenshu:{$sum:{$add:['$class_grade.yuwen','$class_grade.shuxue','$class_grade.yinyu']}}
}
},
{
$sort:{ //最后进行排序
fenshu:-1
}
}
])
如有不正确地方,希望指正,后续也会慢慢完善mongodb的一些使用和操作!