is there a way that I could use a schema attribute within it's own model
var mongoose = require("mongoose");
//====================================================
// Schema
//====================================================
var bookSchema = new mongoose.Schema({
name: String,
image: String,
summary: String,
author: String,
genre: String,
publisher: String,
available: Number,
submitted: {
id: {
type: mongoose.Schema.Types.ObjectId,
ref: "User" //model name
},
username: String
},
reviews: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Review"
}
],
reserves: {
type: [{
type: mongoose.Schema.Types.ObjectId,
ref: "Reserve"
}],
validate: [arrayLimit, '{PATH} exceeds the limit of 5']
}
});
function arrayLimit(val) {
return val.length <= 5;
}
module.exports = mongoose.model("Book", bookSchema);
in the function arraylimit. I'm trying to replace the "5" with the "available" attribute from the bookSchema.
Related
I want to ref a slot by objectid which is inside an array of object in different schema,
Here is my DoctorSlots schema:
const DoctorSlots = new mongoose.Schema({
doctor: { type: mongoose.Schema.Types.ObjectId, ref: 'Doctors' ,required: true ,trim: true},
slots: [{
startTime: {type: Date, },
endTime: { type: Date },
status: {type: String, default: "active"
} //this is the object that i want to ref
}]
},{timestamps: true})
const slotSchema = mongoose.model('doctorslots',DoctorSlots)
this is appointment schema
const AppointmentSchema = new mongoose.Schema({
userDetails: {type: mongoose.Schema.Types.ObjectId, ref: 'User', required:true },
doctorDetails: { type: mongoose.Schema.Types.ObjectId,ref: 'Doctors' ,required: true },
appointTime: {
time: {
type: mongoose.Schema.Types.ObjectId, ref: ''
} //here i want to ref that slot objcet id inside that array
}
}, {timestamps: true})
const appointmentSchema = mongoose.model('appointments', AppointmentSchema)
I want to ref an object in time: field of appointment schema which will refer an object from slots(array of obj) of doctorslots schema. what should be inside " ref:'' "?
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
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);
The field (viewed_posts) i want to populate in User Schema:
viewed_posts: [
{
type: mongoose.Schema.Types.ObjectId,
ref: "Viewed"
}
]
Viewed Schema :
var viewedSchema = new mongoose.Schema({
hitsByUser: {type: Number, default: 0},
viewsByUser: {type: Number, default: 0},
post: {
type: mongoose.Schema.Types.ObjectId,
ref: "Post"
}
});
Post Schema :
var mongoose = require('mongoose');
var passportLocalMongoose = require("passport-local-mongoose");
var uniqueValidator = require('mongoose-unique-validator');
var marked = require('marked');
var slugify = require('slugify');
// this is done for sanitizing html so that user cannot write a script in the input
const createDomPurify = require('dompurify')
const {JSDOM} = require('jsdom')
const dompurify = createDomPurify(new JSDOM().window)
var postSchema = new mongoose.Schema({
postNumber: Number,
title: String,
content: String,
subject: String, // currently we have 4 subjects so one out of 4 subjects will be stored here
likes: {type:Number,default:0},
// likes: {
// id:{
// type: mongoose.Schema.Types.ObjectId,
// ref: "User"
// }
// },
views: {type:Number,default:0},
actualViews: {type:Number,default:0},
shares: Number,
isReviewedByAdmin: {type: Boolean, default: false},
isReviewedByAuditor: {type: Boolean, default: false},
author: {
id:{
type: mongoose.Schema.Types.ObjectId,
ref: "User"
},
username: {
type: String
}
},
publish_date: {
type: String,
default: Date.now
},
publishDay: String,
slug: {
type: String,
required: true,
},
sanitizedHtml: {
type: String,
required: true
},
imagename: String //2002-12-09
});
I wish to see whole structure printed , but i can only populate viewed_posts, how can i populate "post"
which is inside viewed Schema and see here:
User.findById(req.user._id).populate("viewed_posts").exec((err,ans)=>{
if(err) console.log(err)
else{
console.log("this is the answer ",ans)
}})
The output i get:
},
{
hitsByUser: 0,
viewsByUser: 0,
_id: 5f9e85aeec37700f54a4d029,
post: 5f9a93d38d7cf8544ce9cc21,
__v: 0
},
{
hitsByUser: 0,
viewsByUser: 0,
_id: 5f9e85d61841000478c85f8a,
post: 5f82773f1998150024d4c8fc,
__v: 0
},
But i expect this post to be expanded too, instead of just showing id , How can i achieve it. Any Help Would be appreciated.
Mongoose supports nested populating (see in the docs: https://mongoosejs.com/docs/populate.html#deep-populate).
Note that you have to specify your model name of post schema where I´ve put the "post-model-name" placeholder.
So you could try something like this:
User.findById(req.user._id)
.populate({
path: 'viewed_posts',
populate: {
path: 'post',
model: 'post-model-name'
}
})
.exec();
I have a user schema and an exam schema, i wanted to pass the id of the user to the schema of the exam
const ExamSchema = new mongoose.Schema({
-----> _id: [{
class: { type: String, required: true },
module: { type: Number,required:true },
date: {type: Date, required: true }
}]
Where it says _id - i wanted it to be the id of the user! Should i do it like this or add the exams schema on the user schema? Like this?
const UserSchema = new mongoose.Schema({
username: { type: String, require: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
active: { type: Boolean, default: true },
exam: [{
class: { type: String, required: true },
module: { type: Number,required:true },
date: {type: Date, required: true }
}]
});
Check Mongoose "Populate"
https://mongoosejs.com/docs/populate.html
A part from the docs,
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const personSchema = Schema({
_id: Schema.Types.ObjectId,
name: String,
age: Number,
stories: [{ type: Schema.Types.ObjectId, ref: 'Story' }]
});
const storySchema = Schema({
author: { type: Schema.Types.ObjectId, ref: 'Person' },
title: String,
fans: [{ type: Schema.Types.ObjectId, ref: 'Person' }]
});
const Story = mongoose.model('Story', storySchema);
const Person = mongoose.model('Person', personSchema);
So far we've created two Models. Our Person model has its stories field set to an array of ObjectIds. The ref option is what tells Mongoose which model to use during population, in our case the Story model. All _ids we store here must be document _ids from the Story model.
In your case just make a user_id in Exam Schema and refer to id of User Schema
const ExamSchema = new mongoose.Schema({
user_id: {type: Schema.Types.ObjectId, ref: 'User' },
class: { type: String, required: true },
module: { type: Number,required:true },
date: {type: Date, required: true }
})