Filling a nested array in mongoose - Node.js

These are my schemes (Theme is parental and contains the list "Thought"):

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

I am trying to read the author’s thoughts and change my topic “Api-theme” as follows:

 ... 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)); ... 

But the author is empty. I also do not get errors in the console. What is wrong here?

Edit: Actually, I don't need a thought as a schema, it does not have its own collection in the database. It will be saved in sections. But in order to use the timestamps option with thoughts, I needed to extract its contents into a new local ThoughtSchema schema. But I have now defined the contents of thinkSchema directly in the array of thoughts by themes, but it still does not work.

Edit2: This is a cursor object just before its execution. Unfortunately, I cannot debug Webstorm, this is a screenshot from the node inspector:

enter image description here

+7
mongodb mongoose
source share
3 answers

What about

 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
source share

Have you tried using 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:
You can try with deep filling as follows:

 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
source share

These are the schemes:

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

You tried aggregation instead of filling. The aggregate makes it much easier to populate the embedded data with $lookup . Try the code below.

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. }) 

Explanation

$ unwind : Deconstructs an array field from input documents to output a document for each element.

$ lookup : the $ lookup stage matches the equality between the field from the input documents and the field from the documents of the “merged” collection. Search does work with the public.

$ lookup works like

from : this indicates which collection to fill in the data from. ( users in this scenario).

localField : this is the local field to be filled. ( thoughts.author in this case).

foreignField : this is the external field present in the collection from which data needs to be populated ( _id in the users collection in this scenario).

how : this field is like what you want to display the combined value as. (this projects thoughts. author as a document of thoughts. author).

Hope this works.

0
source share

All Articles