I have a mongoose schema field called "bookmarks" and I would like it to reference more than one model. for example, if I have 2 other models named "post" and "complain". I would like the user to be able to bookmark both of them.
const userSchema = new mongoose.Schema({
fullname: {
type: String,
required: true,
trim: true,
lowercase: true
},
username: {
type: String,
unique: true,
required: true,
trim: true,
lowercase: true
},
email: {
type: String,
unique: true,
required: true,
trim: true,
lowercase: true,
validate(value) {
if (!validator.isEmail(value)) {
throw new Error('Email is invalid')
}
}
},
bookmarks: [{
type: mongoose.Schema.Types.ObjectId,
required: false,
ref: 'Post'
}],
})
below is a post model, where users can post things in general
const postSchema = new mongoose.Schema({
body: {
type: String,
required: true,
trim: true,
lowercase: true
}
})
below is a complain model, where users can post a complain
const complainSchema = new mongoose.Schema({
body: {
type: String,
required: true,
trim: true,
lowercase: true
}
})
How can I get the bookmarks field in the user model to be able to get the object id of both the complain model and the post model?
You can nest those two models in userSchema itself just like you are doing with bookmark schema .
You can also refer to this link , i hope it will resolve your query.
Link - : What is the proper pattern for nested schemas in Mongoose/MongoDB?
Here is the correct way to achieve this.
First remove bookmarks
Add this
ref: {
kind: String, // <-- Model Name post,complain
item: {
type: mongoose.Schema.Types.ObjectId,
refPath: 'ref.kind',
fields: String,
},
},
When you want to fetch the records,you can use populate
model.User.find({})
.populate({ path: 'ref.item' })
.then(data=>{console.log(data)})
.catch(err => {console.log(err)});
Related
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
//broken schema
var coursesSchema = new Schema({
college: {
type: String,
required: true
},
units: {
type: Number,
required: true
},
course_code: {
type: String,
required: true
},
course_name: {
type: String,
required: true
},
class_number: {
type: String,
required: true
},
section: {
type: String,
required: true
},
class_day: {
type: String,
required: true
},
time_start: {
type: String,
required: true
},
time_end: {
type: String,
required: true
},
faculty: {
type: String,
required: true
}
});
module.exports = mongoose.model('Courses', coursesSchema);
//working schema
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var loaSchema = new Schema({
process_name: {
type: String,
required: true
},
process_details: {
type: String,
required: true
},
process_deadline: {
type: String,
required: true
},
});
module.exports = mongoose.model('LOA', loaSchema);
I have this schema which I export into index.js file. This schema works in other parts of the code except in index.js. When I query Courses schema, it returns model.find() is not a function. When I try creating a new Courses object it says Constructor is not a schema. I have other schemas that work fine inside index.js and I get to query them, but this schema is an exception.
Does anyone know the reason behind this?
index.js is the special file and actually it's root of your module, it's better separate the schema from that to prevent from bugs
I am new to mongoose and I have searched alot about it and was not able to find out the ans. Please help, thanks in advance.
const user = new mongoose.Schema({
email: {
type: String,
required: true,
unique: true
},
rollno: {
type: Number,
required: true,
unique: true,
},
password : {
type: String,
required: true,
},
isVoter: {
type: Boolean,
required: true,
default: true
}
}, {
timestamps: true
});
Can I have a schema which would be dependent on the value of isVoter. For example if value of isVoter is false then we should have schema like this :
const user = new mongoose.Schema({
email: {
type: String,
required: true,
unique: true
},
rollno: {
type: Number,
required: true,
unique: true,
},
password : {
type: String,
required: true,
},
isVoter: {
type: Boolean,
required: true,
default: true
},
promises: [
{
type: String
}
]
, {
timestamps: true
});
You can defined if one variable is required or not based in another property in this way:
promises: [
{
type: String,
required: function(){
return this.isVoter == false
}
}
]
So, promises will be required only if isVoter is false. Otherwise will not be required.
you can use pre hook in mongoose, check the documentation and before saving, check the isVoter value, if you don't want to save promises, try this.promises = undefined
user.pre('save', function(next) {
if(this.isVoter== true){
this.promises = undefined
}
else{
this.promises = "hello"
//do somethings
}
next();
});
and in the schema promises should be definded
I have two same functions, first saves some stuff and also saves ref to productId and second saves another stuff and saves ref to productId too. The problem is first writes ref to poductId as object and everything is ok but second function saves ref as string and in mongodb i see ObjectId but when im trying to display data on screen i cant access into object i have only string with ID of refer. Any ideas?
first model which is ok
const mongoose = require('mongoose')
const dishPositionsSchema = mongoose.Schema({
productId: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Products'
},
dishId: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Dishes'
},
weight: {
type: Number,
required: true
}
})
module.exports = mongoose.model('DishPositions', dishPositionsSchema)
and second which stores only strings instead of objects
const mongoose = require('mongoose')
const diaryPositionsSchema = mongoose.Schema({
productId: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'Products'
},
dishId: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Dishes'
},
weight: {
type: Number,
required: true,
required: true
},
timeOfEatingId: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'TimeOfEating'
},
date: {
type: String,
required: true
}
})
module.exports = mongoose.model('DiaryPositions', diaryPositionsSchema)
I know where i did mistake... i didnt write populate('productId')... everything is fine now thanks!
I have a user which should have the following fields and currently has following schema:
const UserSchema = new Schema(
{
email: {
type: String,
required: true,
index: { unique: true },
lowercase: true,
},
isVerified: { type: Boolean, default: false }, // whether user has confirmed his email
name: { type: String, required: false },
password: { type: String, required: true, minLength: 6 }, // object with next two included?
passwordResetExpires: Date,
passwordResetToken: String,
roles: [{ type: 'String' }], // Array of strings?
username: { type: String, required: false },
token: [{ type: String, required: false }], // used to send verification token via email
},
{ timestamps: true },
);
So yes, what is the world's default standard for organising user schemas. This schema's fields are pretty common, right?
I have a schema setup like this:
var UserSchema = new Schema({
id: {type: String, required: true, unique: true, index: true, default: mongoose.Types.ObjectId},
name: { type: String, required: true },
email: { type: String, required: true, unique: true, index: true },
mobile: { type: String, unique: true, sparse: true },
password: { type: String, required: true }
});
Seems to work great except the email field is letting in duplicates, despite have unique:true set. I do the following:
User.create({
name: req.body.name,
email: req.body.email,
mobile: req.body.mobile,
password: password
}, function(err, user) {
if (err) return res.send({ invalid : true });
});
If req.body.email is a value that's already in the database, the query above should return err. But it doesn't, it creates the new user perfectly fine, resulting in duplicate emails in the database.
Why is this happening?
mongo and hence mongoose will assign an automatic id fields to your document. usually that is "_id".
Try removing the "id" from your schema to fix your issue.