2016-06-11 22 views
7

Questi sono i miei schemi (topic è genitore e contiene un elenco di 'pensiero di):Popola array nidificato in mangusta - Node.js

var TopicSchema = new mongoose.Schema({ 
    title: { type: String, unique: true }, 
    category: String, 
    thoughts: [ThoughtSchema] 
}, { 
    timestamps: true, 
    toObject: {virtuals: true}, 
    toJSON: {virtuals: true} 
}); 

var ThoughtSchema = new mongoose.Schema({ 
    text: String, 
    author: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, 
    votes:[{ 
    _id:false, 
    voter: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, 
    up: Boolean, 
    date: {type: Date, default: Date.now} 
    }] 
}, { 
    timestamps: true, 
    toObject: {virtuals: true}, 
    toJSON: {virtuals: true} 
}); 

.... 

Sto cercando di leggere l'autore del pensiero e cambiare la mia get topic api così:

... 
    var cursor = Topic.find(query).populate({ 
    path: 'thoughts', 
    populate: { 
     path: 'author', 
     model: 'User' 
    } 
    }).sort({popularity : -1, date: -1}); 

    return cursor.exec() 
    .then(respondWithResult(res)) 
    .catch(handleError(res)); 
... 

Ma l'autore è nullo .. anche io non ho alcun errore nella console. Cosa c'è di sbagliato qui?

Modifica: in realtà non ho bisogno del Pensiero come schema, non ha una propria collezione nel database. Sarà salvato in argomenti. Ma al fine di utilizzare l'opzione timestamp con pensieri, avevo bisogno di estrarne il contenuto in un nuovo schema locale ThoughtSchema. Ma ora ho definito i contenuti del pensieroSchema direttamente nella serie di argomenti, non funziona ancora.

Edit2: questo è l'oggetto cursore prima dell'esecuzione. Purtroppo non posso eseguire il debug in WebStorm, questo è uno screenshot dal nodo ispettore:

enter image description here

+0

@La risposta Theodore mi sembra corretta: qual è il contenuto di 'query'? Avete qualche 'select' in esso? – pasine

+0

ho caricato uno screenshot del contenuto dell'oggetto del cursore appena prima che venga eseguito – akcasoy

risposta

0

Come su

Topic.find(query).populate('thoughts') 
.sort({popularity : -1, date: -1}) 
.exec(function(err, docs) { 
    // Multiple population per level 
    if(err) return callback(err); 
    Topic.populate(docs, { 
    path: 'thoughts.author', 
    model: 'User' 
    }, 
    function(err, populatedDocs) { 
    if(err) return callback(err); 
    console.log(populatedDocs); 
    }); 
}); 
+0

no :(....... – akcasoy

0

Hai provato utilizzando Model.populate?

Topic.find(query).populate('thoughts') 
.sort({popularity : -1, date: -1}) 
.exec(function(err, docs) { 
    // Multiple population per level 
    if(err) return callback(err); 
    Thought.populate(docs, { 
    path: 'thoughts.author', 
    model: 'User' 
    }, 
    function(err, populatedDocs) { 
    if(err) return callback(err); 
    console.log(populatedDocs); 
    }); 
}); 

UPDATE:
si può provare con deep populate come questo:

Topic.find(query).populate({ 
    path: 'thoughts', 
    populate: { 
    path: 'author', 
    model: 'User' 
    } 
}) 
.sort({popularity : -1, date: -1}) 
.exec(function(err, docs) { 
    if(err) return callback(err); 
    console.log(docs); 
}); 
+0

"Thought" non viene esportato Non so anche come esportare più schemi ... Questo è l'unica linea di esportazione: export default mongoose.model ('Topic', TopicSchema); – akcasoy

+0

Non è necessario esportarlo poiché lo si utilizza come schema incorporato. In tal caso, confermo che la risposta di @ Theodore dovrebbe funzionare. controlla il tuo database? Il riferimento a 'autore' è stato salvato correttamente? – pasine

+0

sì .. il campo autore ha l'id dell'utente. Ma in qualche modo non è stato possibile eseguire il debug del codice lato server in webstorm per vedere come appare la query .. prova a eseguire il debug nei giorni seguenti. Ma riguardo allo schema "Pensiero" .. quando uso Thought.populate come suggerisci, l'applicazione non può essere compilata .. sth come "Il pensiero non è definito" appare nel terminale – akcasoy

0

Questi sono gli schemi:

var TopicSchema = new mongoose.Schema({ 
    title: { type: String, unique: true }, 
    category: String, 
    thoughts: [ThoughtSchema] 
}, { 
    timestamps: true, 
    toObject: {virtuals: true}, 
    toJSON: {virtuals: true} 
}); 

var ThoughtSchema = new mongoose.Schema({ 
    text: String, 
    author: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, 
    votes:[{ 
    _id:false, 
    voter: {type: mongoose.Schema.Types.ObjectId, ref: 'User'}, 
    up: Boolean, 
    date: {type: Date, default: Date.now} 
    }] 
}, { 
    timestamps: true, 
    toObject: {virtuals: true}, 
    toJSON: {virtuals: true} 
}); 

Hai provato aggregazione Invece di Popola. Aggrega Rende molto più facile la compilazione dei dati incorporati utilizzando $lookup. Prova il codice qui sotto.

UPDATE

Topic.aggregate([{$unwind: "$thoughts"},{ $lookup: {from: 'users', localField: 'thoughts.author', foreignField: '_id', as: 'thoughts.author'}},{$sort:{{popularity : -1, date: -1}}}],function(err,topics){ 
console.log(topics) // `topics` is a cursor. 
// Perform Other operations here. 
}) 

Spiegazione:

$ rilassarsi: decostruisce un campo di matrice dai documenti in ingresso per produrre un documento per ogni elemento.

$ ricerca: La fase di ricerca $ esegue una corrispondenza di uguaglianza tra un campo dei documenti di input con un campo dei documenti della raccolta "unita". La ricerca fa il lavoro della popolazione.

$ di ricerca funziona come

da: questo dice da cui raccolta i dati devono essere popolata (users in questo scenario)..

localField: questo è il campo locale che deve essere popolato. (thoughts.author in questo scenario).

foreignField: questo è il campo straniero presente nella collezione da cui ha bisogno di dati per essere popolato (_id campo in users raccolta in questo scenario).

come: questo è il campo in cui si desidera visualizzare il valore unito come. (questo proietterà l'id di thoughts.author come documento thoughts.author).

Spero che questo funzioni.

+0

"Hai provato l'aggregazione invece di popolare" Scusa .. Ma l'aggregazione è normalmente utilizzata con "match" invece di "find" per quanto ne so .. quindi non è un'alternativa per popolare ma per "trovare" penso .. quindi non so come integrare questo nel mio codice .. aggrega anche un oggetto cursore, che deve essere eseguito successivamente? Potresti aggiornare il mio secondo codice nella domanda e scrivere tutte le righe? – akcasoy