mongoose聚合——$group
$group:将集合中的文档分组
数据表
//Students
[{"_id":"60adff66e57f4255b4c7e19a", "name":"唐戚", "student_id":232323, "class_oid":"60adff65e57f4255b4c7e194", "come_year":"2020-01-01T00:00:00.000Z", "grade":{"math":37,"chinese":98,"english":71}, "__v":0 } .....省略16条 {"_id":"60ae02937e294b5894229d70", "name":"安俞", "student_id":232328, "class_oid":"60adff65e57f4255b4c7e199", "come_year":"2021-01-01T00:00:00.000Z", "grade":{"math":29,"chinese":39,"english":79}, "__v":0 }]
代码
示例中只给出aggregate中的参数,文末给出完整代码
1.通过某个字段分组
这里使用come_year分组,数据中有两个年份,2020和2021,$group是通过_id来分组。
聚合参数:
const query=[ { $group:{ _id:'$come_year' } } ]
结果:
[ { _id: 2020-01-01T00:00:00.000Z }, { _id: 2021-01-01T00:00:00.000Z } ]
2.数学运算
找出在2020年和2021年入学学生中各科成绩最高分,最低分,平均分
使用:$max:该分组中最大值
$min:该分组中最小值
$avg:该分组的平均值
$sum:计算总和,$sum:1表示返回总和的1倍
const query=[
{
$group:{
_id:'$come_year',
maxEnglish:{$max:'$grade.english'},
minEnglish:{$min:'$grade.english'},
avgEnglish:{$avg:'$grade.english'},
total:{$sum:1}
}
}
]
结果:
[ { _id: 2020-01-01T00:00:00.000Z, maxEnglish: 74, minEnglish: 5, avgEnglish: 42.25, total: 12 }, { _id: 2021-01-01T00:00:00.000Z, maxEnglish: 84, minEnglish: 39, avgEnglish: 63.666666666666664, total: 6 } ]
3.在分组中插入字段
获得不同学年有哪些学生,给出姓名
使用$addToSet:在结果文档中插入一个数组
const query=[ { $group:{ _id:'$come_year', test:{$addToSet:'$name'} } } ]
结果:
[ { _id: 2020-01-01T00:00:00.000Z, test: [ '凤殷', '吴于', '韩马', '尤郝', '喻蒋', '曹罗', '钱许', '唐戚', '卜严', '谢柳', '薛金', '俞彭' ] }, { _id: 2021-01-01T00:00:00.000Z, test: [ '花唐', '酆史', '朱吴', '平殷', '安俞', '邹尤' ] } ]
4.计算文档总数
计算有多少学生
可以将_id设为null,就不分组
const query=[
{
$group:{
_id:null,
total:{$sum:1}
}
}
]
结果:
[ { _id: null, total: 18 } ]
5.插入新增字段
获取不同学年学生信息
使用$push:在结果文档中插入值到数组中,和addToSet不同的是,$push要创建副本
const query=[ { $group:{ _id:'$come_year', students:{ $push:{ _id:'$_id', name:'$name', grade:'$grade' } } } } ]
结果:
[ { _id: 2020-01-01T00:00:00.000Z, students: [ [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object], [Object] ] }, { _id: 2021-01-01T00:00:00.000Z, students: [ [Object], [Object], [Object], [Object], [Object], [Object] ] } ]
完整代码
const Articles = require('../../model/articles');
const Users = require('../../model/users');
var Departments=require('../../model/departments');
var Students=require('../../model/students');
var Classes=require('../../model/classes');
//$group:将集合中的文档分组
//语法:{ $group: { _id: <expression>, <field1>: { <accumulator1> : <expression1> }, ... } }
//---------------------------------1-----------------
//按照入学日期分组
/*
[
{ _id: 2020-01-01T00:00:00.000Z },
{ _id: 2021-01-01T00:00:00.000Z }
] */
async function group1(){
const query=[
{
$group:{
_id:'$come_year'
}
}
]
await studentsAggregate([...query])
}
//----------------2----------------
//找出在2020年和2021年入学学生中各科成绩最高分,最低分,平均分
/**
* [
{
_id: 2020-01-01T00:00:00.000Z,
maxEnglish: 74,
minEnglish: 5,
avgEnglish: 42.25,
total: 12
},
{
_id: 2021-01-01T00:00:00.000Z,
maxEnglish: 84,
minEnglish: 39,
avgEnglish: 63.666666666666664,
total: 6
}
]
*/
async function group2(){
const query=[
{
$group:{
_id:'$come_year',
maxEnglish:{$max:'$grade.english'},
minEnglish:{$min:'$grade.english'},
avgEnglish:{$avg:'$grade.english'},
total:{$sum:1}
}
}
]
await studentsAggregate([...query])
}
//------------------3----------------
//插入数组到分组中
/*
[
{
_id: 2020-01-01T00:00:00.000Z,
test: [
'凤殷', '吴于', '韩马',
'尤郝', '喻蒋', '曹罗',
'钱许', '唐戚', '卜严',
'谢柳', '薛金', '俞彭'
]
},
{
_id: 2021-01-01T00:00:00.000Z,
test: [ '花唐', '酆史', '朱吴', '平殷', '安俞', '邹尤' ]
}
]
*/
async function group3(){
const query=[
{
$group:{
_id:'$come_year',
test:{$addToSet:'$name'}
}
}
]
await studentsAggregate([...query])
}
//---------------4------------
//常用计算总数
//[ { _id: null, total: 18 } ]
async function group4(){
const query=[
{
$group:{
_id:null,
total:{$sum:1}
}
}
]
await studentsAggregate([...query])
}
//----------------------5---------------
//获取不同学年的学生信息
async function group5(){
const query=[
{
$group:{
_id:'$come_year',
students:{
$push:{
_id:'$_id',
name:'$name',
grade:'$grade'
}
}
}
}
]
await studentsAggregate([...query])
}
/**
* articles聚合结果模板
* @param {Array} query 聚合的参数
*/
async function studentsAggregate(query) {
try {
const result = await Students.aggregate([
...query
])
console.log(result);
} catch (err) {
console.log((query))
console.log("聚合失败...", err)
}
}
function main(){
group5();
}
main();

浙公网安备 33010602011771号