mongodb聚合:平均和sorting

我是一个新手,并有一个MongoDB聚合的问题。 我用mongoose。

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, }); 

所以,input数据是这样的。

 { _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 ] 

我试图跟随,但我无法得到名字,configuration文件的领域。 所以我需要额外的查询来获取名称和个人资料字段和重新sorting。

  {$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) 
  1. 我想知道如何保留不需要聚合的字段,但需要显示结果。 如果这是不可能的,我需要额外的查询结果我想要的?

  2. 有没有另一种方法来考虑性能得到这个结果?

我已经把这个工作放了几天,并用googlesearch,但没有得到答案。 请帮帮我。

谢谢。

您在第一个操作中丢失了信息,因为$project只是沿着主键的值发送。

保持字段值不受聚合计算( nameprofile )影响的操作是$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 }