2014-09-30 13 views
5

Ho un elenco di studenti in una raccolta e i loro voti in un'altra raccolta. Lo schema (spogliato di altri dettagli) sembraQuery aggregata Mongodb con non in

studenti

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

gradi

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

Non ci possono essere più voci di grado per ogni studente. Ho bisogno di un numero totale di studenti che sono presenti nella tabella dei voti ma non nel tavolo dello studente. Ho anche bisogno di un conteggio dei voti per ogni studente che non è nella tabella degli studenti. Quanto segue è la query che avevo scritto,

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

Ma questo mi restituisce tutti i dettagli degli studenti, come se la partita non sta funzionando. Quando eseguo solo la prima parte di questa domanda, ottengo i dettagli degli studenti come

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

ritengo che, poiché il valore di ritorno è a due profondità il funzionamento partita isnt. Qual è il modo giusto per ottenere questo?

+0

db.students.find ({}, {_id: 0, 'student.code': 1}) non ti dà array di codici di studenti. Fornisce una serie di documenti contenenti FieldCode.Sodes $ nin non lo riconosce. – mallik

risposta

8

Usa questo codice

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

Grazie. Questo ha funzionato! – etrast81

+0

@mallik, $ nin operatore usa il formato array. aggiorna la tua risposta nel seguente formato. {$ nin: ['value1', 'value2']} –

+0

Se stai usando _id in o not in, usa gentilmente questo => ids = ids.map (function (el) {return mongoose.Types.ObjectId (el) }) –

Problemi correlati