我是一个新手,并且有一个mongodb聚合问题。我用猫鼬。
var SubjectScore = new Schema({
name: {type:String, required:true}, //math, science, history, ...
score: {type:Number, required:true } // 95, 85, 77,....
});
var Subject = new Schema({
year: Number, //2012, 2013, 2014
subjectScore : [SubjectScore]
});
var StudentSchema = new Schema({
name: String,
subject: [Subject], //array length varies for each student
profile: String,
});
所以,输入数据是这样的。
{ _id: 54c921aaa7918d4e4a8c7e51,
name: John,
profile: "He is nice",
subject: [{ year: 2010,
subjectScore: [{ name:"history" score:66},
{ name:"math", score:65},
{ name:"science", score:87}] }]
},{ year: 2011,
subjectScore: [{ name:"history" score:75},
{ name:"math", score:61},
{ name:"science", score:92}] }]
},{ year: 2012,
subjectScore: [{ name:"history" score:83},
{ name:"math", score:82},
{ name:"science", score:86}] }]
},{ year: 2013,
subjectScore: [{ name:"history" score:77},
{ name:"math", score:99},
{ name:"science", score:71}] }]
}]
}
我想得到的最终结果如下。
[
{ _id: "54c921aaa7918d4e4a8c7e51",
name: "John"
profile: "He is nice",
avgScore: [
{name: "math", score: 77},
{name:"history", score:78},
{name:"science", score:86} ]
totalAvg: 82
},
{ _id: "54c921aaa7918d4e4a8c7e5b",
name: "Mary"
profile: "She is kind",
avgScore: [
{name: "math", score: 67},
{name:"history", score:99},
{name:"science", score:96} ]
totalAvg: 82
},
{ _id: "54c921aaa7918d4e4a8c7e56",
name: "Jane"
profile: "She is smart",
avgScore: [
{name: "math", score: 99},
{name:"history", score:99},
{name:"science", score:99} ],
totalAvg: 99
}
..... // 7 more student for first page result
]
我试过了,但我无法获得名称,个人资料的字段。所以我需要额外的查询来获取名称和配置文件字段并再次排序。
{$project:{subject:1}},
{$unwind:"$subject"},
{$unwind:"$subject.subjectScore"},
{$group:{_id:{studentId:"$_id", subjectName:"$subject.subjectScore.name"},
avgScore:{$avg: "$subject.subjectScore.score"}}},
{$group:{_id:"$_id.studentId",
avgScore:{$push: {name:"$_id.subjectName", score:"$avgScore"}},
totalAvg:{$avg:"$avgScore"}}},
{$sort:{totalAvg:-1}},
{$limit:10} // for first page (students per page : 10)
我想知道如何保留聚合不需要的字段,但需要显示结果。如果不可能,我是否需要对我想要的结果进行额外查询?
考虑到性能,还有其他方法可以获得此结果吗?
我已经花了几天时间来完成这项工作和谷歌搜索,但没有得到答案。请帮帮我。
谢谢。
答案 0 :(得分:1)
您在第一次操作中丢失了信息,因为$project
仅发送subject
密钥的值。
保持字段值不受聚合计算(name
和profile
)影响的操作与$first
一致。它只会获取该字段的第一个值,该值应与其余字段相同。
{ $unwind: "$subject" },
{ $unwind: "$subject.subjectScore" },
{ $group: { _id: { sId: "$_id", subjectName: "$subject.subjectScore.name" },
avgScore: { $avg: "$subject.subjectScore.score" },
name: { $first: "$name" },
profile: { $first: "$profile" } } },
{ $group: { _id: "$_id.sId",
name: { $first: "$name" },
profile: { $first: "$profile" },
avgScore: { $push: { name: "$_id.subjectName", score: "$avgScore" } },
totalAvg: { $avg: "$avgScore" } } }
{ $sort: { totalAvg: -1 } }, // this is sorting desc, but sample is asc?
{ $limit: 10 }