How to define a proper mongoose schema? - mongodb

Is this a proper way to define it?
const mongoose = require("../database");
// create a schema
var userschema =new mongoose.Schema({
name: String,
password: String,
email:String
});
var userModel=mongoose.model('users',userSchema);
module.exports = mongoose.model("Users", userModel);

//Please Try In This Way
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const User = mongoose.Schema(
{
name: {
type: String,
default: "",
trim: true,
},
email: {
type: String,
default: "",
trim: true,
validate: {
validator: async function (email) {
const user = await this.constructor.findOne({ email });
if (user) {
if (this.id === user.id) {
return true;
}
return false;
}
return true;
},
message: (props) => "This email is already in use",
},
required: [true, "User email required"],
},
password: {
type: String,
default: "",
trim: true,
select: false,
},
mobile: {
type: String,
default: "",
trim: true,
},
experience: {
type: String,
default: "",
trim: true,
},
agree: {
type: Array,
default: "",
trim: true,
},
status: {
type: Number,
default: 1,
},
type: {
type: String,
},
isDelete: {
type: Boolean,
default: false,
},
},
{
timestamps: { createdAt: "createdAt", updatedAt: "updatedAt" },
}
);
module.exports = mongoose.model("User", User);

Related

Re: Correct MongoDb Relationships

Hi clever MongoDB people,
I am extremely new to Mongo DB and am trying to teach myself coding but I am battling with the practical side of collections.
I am attempting to create an employee management system and would like to know how do I get the different schemas/collections to only deal with the individual User’s employees.
A user will register using this schema;
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
email: {
type: String,
required: true,
lowercase: true,
},
companyName: {
type: String,
required: true,
},
password: {
type: String,
required: true,
},
role: {
type: String,
default: "customer",
},
CreatedAt: {
type: Date,
default: () => Date.now(),
},
UpdatedAt: {
type: Date,
default: () => Date.now(),
},
});
const User = mongoose.model("User", UserSchema:
);
module.exports = User;
Then the system takes them to a Profile page where they create a profile;
Profile Schema:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const ProfileSchema = new Schema({
userId: {
type: Schema.Types.ObjectId,
required: true,
},
contactPerson: {
type: String,
required: true,
},
companyName: {
type: String,
required: true,
},
mobileNo: {
type: String,
required: true,
},
workNo: {
type: String,
},
email: {
type: String,
required: true,
},
industry: {
type: String,
},
CreatedAt: {
type: Date,
default: () => Date.now(),
},
UpdatedAt: {
type: Date,
default: () => Date.now(),
},
});
const Profile = mongoose.model("Profile", ProfileSchema);
module.exports = Profile;
Then they can add their employees.
Employee Schema:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const EmployeeSchema = new Schema({
userId: {
type: Schema.Types.ObjectId,
required: true,
},
employeeNo: {
type: String,
},
title: {
type: String,
},
employeeName: {
type: String,
required: true,
},
surname: {
type: String,
required: true,
},
gender: {
type: String,
},
race: {
type: String,
},
passportNo: {
type: String,
},
IDnumber: {
type: Number,
},
DOB: {
type: Date,
},
aka: {
type: String,
},
midName: {
type: String,
},
marriage: {
type: String,
},
passportExpires: {
type: Date,
},
mobileNo: {
type: String,
},
empEmail: {
type: String,
lowercase: true,
},
CreatedAt: {
type: Date,
default: () => Date.now(),
},
UpdatedAt: {
type: Date,
default: () => Date.now(),
},
});
const Employee = mongoose.model("Employee", EmployeeSchema);
module.exports = Employee;
Once an employee has been created there are various schemas connected with the employee, such as Personal contact details schema, Job details schema, Emergency contact details schema and so on.
This is my Emergency contact details schema:
const mongoose = require("mongoose");
const Schema = mongoose.Schema;
const EmergencySchema = new Schema({
userId: {
type: Schema.Types.ObjectId,
required: true,
},
emergContactPerson: {
type: String,
required: true,
},
emergWorkNo: {
type: String,
},
emergMobileNo1: {
type: String,
required: true,
},
emergMobileNo2: {
type: String,
},
medicAidName: {
type: String,
},
medicPlan: {
type: String,
},
medicMemberNo: {
type: String,
},
medicDepCode: {
type: Number,
},
CreatedAt: {
type: Date,
default: () => Date.now(),
},
UpdatedAt: {
type: Date,
default: () => Date.now(),
},
});
const Emergency = mongoose.model("Emergency", EmergencySchema);
module.exports = Emergency;
My question is How do I create a one-to-many relationship between my schemas so that each User will only see their employees and their personal details?
Please can you help me?

how to create nested schema in nestjs use mongodb

email
password
role
confirmed
id
address
city
street
My user schema should be like this. I want it to appear as a nested schema. separate the address space.
export const UserSchema = new mongoose.Schema({
email: { type: String, unique: true, required: true },
password: { type: String, required: true },
role: { type: String, enum: Role, default: Role.USER },
confirmed: { type: Boolean, default: false },
id: { type: String, default: uuid.v4 },
});
UserSchema.pre('save', async function (next) {
try {
if (!this.isModified('password')) {
return next();
}
const hashed = await bcrypt.hash(this['password'], 10);
this['password'] = hashed;
return next();
} catch (err) {
return next(err);
}
});
interface user
export interface User extends Document {
id:string;
email: string;
password: string;
role: Role[];
address: ?
}
I have to add the address in user. How?
export const AddrSchema= new mongoose.Schema({
city: { type: String, default: "bb" },
street: { type: String, default: "aa" },
})
I think this will solve it.
export const UserSchema = new mongoose.Schema({
email: { type: String, unique: true, required: true },
password: { type: String, required: true },
role: { type: String, enum: Role, default: Role.USER },
confirmed: { type: Boolean, default: false },
id: { type: String, default: uuid.v4 },
address: {
city: { type: String, default: "bb" },
street: { type: String, default: "aa" },
}
});

Mongoose error with PUT request but not with POST or GET

I have a schema that looks like:
const houseSchema = new mongoose.Schema({
address: {
type: String,
required: true,
trim: true,
},
city: {
type: String,
required: true,
},
roofType: {
type: String,
//required: true,
},
repairType: {
type: String,
//required: true,
},
numFloors: {
type: Number,
//required: true,
},
isOwner: {
type: Boolean,
//required: true,
},
isGated: {
type: Boolean
},
includeFlat: {
type: Boolean
},
addedBy: [
{
name:{
type: String
},
time:{
type: String
},
}
],
});
const customerSchema = new mongoose.Schema({
firstName: {
type: String,
required: true,
trim: true,
},
lastName: {
type: String,
required: true,
trim: true,
},
phoneNumber: {
type: String,
required: true,
},
email: {
type: String,
},
//array of houseSchema objects
properties: [
houseSchema
],
});
And my endpoint that is used to update one of the 'properties' is:
router.route('/property').post(async (req,res) => {
const body = req.body;
Customer.updateOne({_id: req.query.id, properties: {$elemMatch: {_id: req.query.pId}}},
{
$set: {
"properties.$.address": body.address,
"properties.$.city": body.city,
"properties.$.roofType": body.roofType,
"properties.$.repairType": body.repairType,
"properties.$.numFloors": body.numFloors,
"properties.$.isOwner": body.isOwner,
"properties.$.isGated": body.isGated,
"properties.$.includeFlat": body.includeFlat
}
},
function(err){
if(err){
res.status(400).json('Error: ' + err);
}
else{
res.json('Property Updated!');
}
}
)
});
The endpoint works mostly fine (it returns the customer and all properties when i only search for and want to modify one of the 'properties') but only when it is a post or a get request and when it is a put request, the error says
Error: ValidationError: firstName: Path firstName is required., lastName: Path lastName is required., phoneNumber: Path phoneNumber is required.
I dont know if its a big deal or not, but I do not know why this is happening and would like to know. Just to be clear, the goal of this endpoint is to find one of the properties and update its values, not to change anything about a customer or any of their other properties.

MongoDB: Find items with the user id

I have a product collection and a user collection where I reference user to my product collection.
So far what I am trying to achieve here is to get only the products that are created by that user.
const getOwnerProduct = expressAsyncHandler(async (req, res) => {
const activeUser = await User.findById(req.user._id)
const pageSize = 10
const page = Number(req.query.pageNumber) || 1
const items = { user: { _id: activeUser } }
const count = await Product.countDocuments({ ...items } )
const products = await Product.find({ ...items }).limit(pageSize).skip(pageSize * (page - 1))
res.json({ products, page, pages: Math.ceil(count / pageSize) })
})
Here's the Product Schema:
const productSchema = mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
required: true,
ref: 'User'
},
name: {
type: String,
required: true
},
price: {
type: Number,
required: true,
},
description: {
type: String,
required: true
},
email: {
type: String
},
rating: {
type: Number,
required: true,
default: 0
},
image: {
type: String,
required: true,
default: 0
},
}, { timestamps: true
})
And here's the userSchema:
const userSchema = mongoose.Schema({
name: {
type: String,
required: true
},
email: {
type: String,
required: true,
unique: true
},
phone: {
type: String,
required: true,
unique: true
},
password: {
type: String,
required: true
},
role: {
type: String,
enum: ['administrator', 'productOwner', 'regular'],
default: 'regular'
}
}, { timestamps: true
})
Here's the router:
app.use('/api/products', productRoutes)
router.route('/').get(getProducts, admin).get(getOwnerProducts, productOwner)
For some reason this doesn't work. I think my query on mongodb is not correct.
Any idea what am I missing here?
Here instead of const products = await Product.find({ ...items }) you can try
await User.findById(req.user._id).forEach(element =>{Product.find({user=element._id})});
or
await User.findById(req.user._id).forEach(element =>{Product.find(user=element._id)});

MongoDB (mongoose) about refs

who can explain with example how to get from another schema user data (for example useravatar)
while i read about refs and i cant understand.
This is my code, but i want to send back not only article but with profile datas about author. How can i do this ? I have authorID already for this.
router.post('/get-article', (req, res) => {
const { id, authorID } = req.body.data;
Article.findByIdAndUpdate({ _id: id }, { $inc: { "pageview": 1 } }, (err, article) => {
if (err) return res.status(400).json({ NotFound: "Article Not Found" })
res.json({ article })
})
})
article schema
const schema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
title: { type: String, required: true },
image: { type: String, required: true },
content: { type: String, required: true },
email: { type: String, required: true },
author: { type: String, required: true, index: true },
added: { type: Date, default: Date.now },
pageview: { type: Number, default: 0 }
});
User schema
const schema = new mongoose.Schema({
_id: mongoose.Schema.Types.ObjectId,
username: { type: String, required: true },
email: { type: String, required: true },
facebookId: { type: String },
githubId: { type: String },
googleId: { type: String },
useravatar: { type: String, required: true },
userip: { type: String, required: true },
accessToken: { type: String },
date: { type: Date, default: Date.now }
});