mongoose populate nested schema without model - node.js

I'm trying to populate nested schemas without creating Model for the subschema, without any success.
I have a 'Question' Model, which created by 2 Schemas(Question, Option)
const Option = new mongoose.Schema({
value: { type: String, required: true }
})
const Question = new mongoose.Schema({
content: { type: String, required: true },
options: [Option]
})
module.exports = mongoose.model('Question', Question)
And I have a 'Review' Model
const Review = new mongoose.Schema({
results: [
{
question: { type: mongoose.Schema.Types.ObjectId, ref: 'Question' },
option: { type: mongoose.Schema.Types.ObjectId, ref: 'Question.options' }
}
],
critical: { type: Boolean, default: false }
})
module.exports = mongoose.model('Review', Review)
Well, I want to create API /reviews that response array of review document, but populate the question and option.
I try this command but it isn't working.
Model.find({}).populate('results.option')
any idea?

as populate can't reference the array of subdocuments, as you have separate Option schema, why not use that.
const Review = new mongoose.Schema({
results: [
{
question: { type: mongoose.Schema.Types.ObjectId, ref: 'Question' },
option: { type: mongoose.Schema.Types.ObjectId, ref: 'Option' }
}
],
critical: { type: Boolean, default: false }
})
module.exports = mongoose.model('Review', Review)

Related

How to populate a data for a field in mongoose, where reference is a nested array in model?

How can I populate category in courses model?
I have courses, courses will have category from categories->subcategories model.
I don't know how to populate from nested objects.
Reference model is category, I have to populate from array subcategories!
**courses:**
const CourseSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String
},
description: {
type: String
},
category: {
type: mongoose.Schema.Types.ObjectId,
ref: 'category'
}
});
**category:**
const mongoose = require("mongoose");
const CategorySchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String,
required: true
},
subcategories: [{
name: {
type: String
}
}]
});
const Category = mongoose.model('category', CategorySchema);
module.exports = Category;
use seprate collection for subCetagory like:
**courses**
const CourseSchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String
},
description: {
type: String
},
category: {
type: mongoose.Schema.Types.ObjectId,
ref: 'SubCategory'
}
});
**SubCategory:**
const mongoose = require("mongoose");
const SubCategorySchema = new mongoose.Schema({
name: {
type: String,
required: true
},
categorie: {
type: String,
ref: "category"
}
});
const SubCategory = mongoose.model('category', SubCategorySchema);
module.exports = SubCategory;
**Category**
const mongoose = require("mongoose");
const CategorySchema = new mongoose.Schema({
userId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'users'
},
name: {
type: String,
required: true
},
subcategories: [
{
type: Schema.types.objectId,
ref: "SubCategory"
}
]
});
then just add subcetagory id to course when insert new course or update a course and when you want to get course along with subcetagory and category use populate query of mongoose

How can i display products per each category stored in MongoDB

currently i created a schema for storing products using mongoose as below
const Schema = mongoose.Schema;
const ProductSchema = new Schema({
title: {
type: String,
required: true
},
price: {
type: Number,
required: true
},
description: {
type: String,
required: true
},
quantity: {
type: Number,
required: true
},
manufacture: {
type: String,
required: true
},
creator: {
type: Schema.Types.ObjectId,
ref: 'user'
},
category: {
type: Schema.Types.ObjectId,
ref: 'category'
}
});
module.exports = { Product: mongoose.model('product', ProductSchema) };
and here another schema for storing categories that products are related to
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const CategorySchema = new Schema({
title: {
type: String,
required: true
}
});
module.exports = { Category: mongoose.model('category', CategorySchema) };
each product is related to a category
the question is how can i display all products that are related to a specific category.
i tried .find() method but i can't use it correctly.
thanks for any advice
You need to use .populate('category'), after .find() in order to populate all the connected data.
products.find().populate('category').exec((err, product) => { })

Mongoose model how to have an array as property which contains same model as parent

So what I'm trying to do is I want to create a Note object inside note I have a subnote property, I want to have the subnote to be able to be as the same type as the parent model, Right now I'm achieving this by creating two same models with different names and both of them referencing each other for e.x this is the way I'm doing it:
Note schema:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const noteSchema = new Schema({
icon: {
type: String,
},
banner: {
type: String,
},
name: {
type: String,
required: true,
},
user_id: {
type: String,
required: true,
},
date: {
type: Date,
required: true,
default: Date.now,
},
sub_note: {
type: mongoose.Schema.Types.ObjectId,
ref: "sub_notes",
},
content: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "blocks",
},
],
});
module.exports = Note = mongoose.model("notes", noteSchema);
SubNote schema:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const subNoteSchema = new Schema({
icon: {
type: String,
},
banner: {
type: String,
},
name: {
type: String,
required: true,
},
user_id: {
type: String,
required: true,
},
date: {
type: Date,
required: true,
default: Date.now,
},
sub_note: {
type: mongoose.Schema.Types.ObjectId,
ref: "notes",
},
content: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "blocks",
},
],
});
module.exports = SubNote = mongoose.model("sub_notes", subNoteSchema);
But I'm not sure if the above method is the proper way to do it..., Please guide me. Thanks.
u can achieve this by simply doing this
const noteSchema = new Schema({
sub_note: {
type: mongoose.Schema.Types.ObjectId,
ref: "notes",
},
});
module.exports = Note = mongoose.model("notes", noteSchema);
or simply using "this" keyword
const noteSchema = new Schema({
sub_note: this
});
module.exports = Note = mongoose.model("notes", noteSchema);

How to populate fields present inside a map type schema in mongoose?

I have my mongoose schema as follow
const instructorSchema = new mongoose.schema({
coursesByMe: [
{
course: {
type: ObjectId,
ref: "Course",
},
submissions: {
type: Map,
of: Submission.schema,
},
},
],
active: {
type: Boolean,
default: false,
},
});
My submission schema is a simple schema
const submissionSchema = new mongoose.Schema({
user: {
type: ObjectId,
ref: "User",
},
subFile: String,
});
module.exports = mongoose.model("Submission", submissionSchema);
I want to populate the user field but I am unable to as the type of submissions is of map type schema.
Any help with this would be really grateful. Thank you.

Mongoose populate array of object ids

I'm trying to populate my Thread schemas GET response with all the comments related that that specific thread. I've specified a path within the Thread model to accept an array of Comments that I'll then populate when I request a thread, but it's continuing to be empty.
I'm not sure if I then need to push all the comments into the thread, but I think with the way I'm doing it, it's not required? I'm using Mongoose 4.4.19. I've followed along with the docs but still can't figure out where I've gone wrong.
Thread Schema:
const threadSchema = new Schema({
user: {
type: Schema.ObjectId,
ref: 'User',
required: true
},
title: {
type: String
},
content: {
type: String
},
category: {
type: String
},
comments: [{
type: Schema.ObjectId,
ref: 'Comment'
}]
}, {
timestamps: true
})
Comment Schema:
const commentSchema = new Schema({
user: {
type: Schema.ObjectId,
ref: 'User',
required: true
},
thread: {
type: Schema.ObjectId,
ref: 'Thread',
required: true
},
content: {
type: String
}
}, {
timestamps: true
})
Handles get requests:
export const index = ({ querymen: { query, select, cursor } }, res, next) =>
Thread.find(query, select, cursor)
.populate('user comments')
.then(threads => threads.map(thread => thread.view()))
.then(success(res))
.catch(next)

Resources