2014-09-30 141 views
5

我有一个集合中的学生列表以及他们在另一个集合中的成绩。架构(剥离的其他细节)看起来像Mongodb聚合查询不在

学生

{ 
    _id: 1234, 
    student: { 
     code: "WUKD984KUK" 
    } 
} 

等级

{ 
    _id: 3456, 
    grade: 24, 
    studentCode: "WUKD984KUK" 
} 

可以有每个学生的多级条目。我需要总计在校成绩表中的学生,但不在学生表中。我还需要为不在学生表中的每个学生计分。以下是我写的查询,

var existingStudents = db.students.find({}, {_id: 0, 'student.code': 1}); 

db.grades.aggregate(
    {$match: { 'studentCode': {'$nin': existingStudents}}}, 
    {$group: {_id: '$studentCode', count:{$sum: 1}}}, 
    {$project: {tmp: {code: '$_id', count: '$count'}}}, 
    {$group: {_id: null, total:{$sum:1}, data:{$addToSet: '$tmp'}}} 
); 

但是,这返回了我所有的学生的详细信息,就好像比赛不工作。当我刚刚运行此查询的第一部分,我得到了学生的细节

{ "student" : { "code" : "A210225504104" } } 

我觉得,因为返回值是两道深深的比赛心不是工作。什么是正确的方式来得到这个?

+0

db.students.find({},{_id:0, 'student.code':1})不给你的学生守则阵列。它给你一些包含字段studentCodes的文档。所以$ nin不能识别它。 – mallik 2014-09-30 10:02:31

回答

8

使用此代码

var existingStudents=[]; 
db.students.find({}, {_id: 0, 'student.code': 1}).forEach(function(doc){existingStudents.push(doc.student.code)}) 

db.grades.aggregate(
    {$match: { 'studentCode': {'$nin': existingStudents}}}, 
    {$group: {_id: '$studentCode', count:{$sum: 1}}}, 
    {$project: {tmp: {code: '$_id', count: '$count'}}}, 
    {$group: {_id: null, total:{$sum:1}, data:{$addToSet: '$tmp'}}} 
); 
+0

谢谢。这工作! – etrast81 2014-10-08 05:07:34

+0

@mallik,$ nin操作符使用数组格式。以以下格式更新您的答案。 {$ nin:['value1','value2']} – 2016-03-28 05:46:46

+0

如果你正在使用_id或不在中,请使用this => ids = ids.map(function(el){return mongoose.Types.ObjectId(el) }) – 2017-07-06 12:55:01