2014-09-30 142 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