2014-09-30 19 views
5

Ich habe eine Liste von Studenten in einer Sammlung und ihre Noten in einer anderen Sammlung. Das Schema (gestrippt anderer Details) sieht aus wieMongodb Aggregat Abfrage mit nicht in

Studenten

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

Grad

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

Es kann mehr Grade Einträge für jeden Schüler sein. Ich brauche eine Gesamtzahl von Schülern, die in der Tabelle der Noten, aber nicht in der Tabelle der Schüler anwesend sind. Ich brauche auch eine Anzahl von Noten für jeden Schüler, der nicht im Schülertisch ist. Folgendes ist die Abfrage, die ich geschrieben hatte:

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

Aber das gibt mir alle Schülerdetails zurück, als ob das Spiel nicht funktioniert. Als ich gerade den ersten Teil dieser Abfrage ausführen, bekomme ich die Schüler Details wie

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

Ich glaube, dass, weil der Rückgabewert zwei tief das Spiel ist nicht arbeiten. Was ist der richtige Weg, um das zu bekommen?

+0

db.students.find ({}, {_id: 0, 'student.code': 1}) nicht geben Sie Array von Studenten Codes. Es gibt Ihnen ein Array von Dokumenten mit dem Feld studentCodes.So $ nin erkennt es nicht. – mallik

Antwort

8

Mit diesem Code

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

Danke. Das hat funktioniert! – etrast81

+0

@mallik, $ nin Operator verwendet Array-Format. Aktualisiere deine Antwort im folgenden Format. {$ nin: ['value1', 'value2']} –

+0

Wenn du _id in oder nicht in verwendest, nutze dies bitte => ids = ids.map (function (el) {return mongoose.Types.ObjectId (el) }) –

Verwandte Themen