DEV Community

Cover image for MongoDB Complex Schemas Structures
Sandeep
Sandeep

Posted on

MongoDB Complex Schemas Structures

today i am writing about mongodb schemas structures and how we handle complex schema in our nodejs application.

model.js

const mongoose=require('mongoose')
const jwt=require('jsonwebtoken')
const config=require('config')

const {Schema,model}=mongoose

const employeeSchema=new Schema({
    fullName:{
        type:String,
        required:true
    },
    email:{
        type:String,
        required:true,
        unique:true
    },
    phone:{
        type:String,
        required:true,
        unique:true
    },
    //userID auto generated By System
    userID:{
        type:String,
        required:true,
        unique:true 
    },
    password:{
        type:String,
        required:true
    },
    avatar:{
        type:String,
        default:'avatar.png'
    },
    employeeTitle:{
        type:String,
        default:null
    },
    employeeField:{
        type:String,
        default:null
    },
    skills:{
        type:Array
    },
    worksWith:[{
        type:Schema.Types.ObjectId,
        ref:'Company'
    }],
    address:{
        type:String,
        default:null
    },
    isVerified:{
        type:Boolean,
        default:false
    }
},{timestamps:true})

employeeSchema.methods.generateEmployeeToken=function (){
    return jwt.sign({id:this._id,email:this.email,phone:this.phone},config.get('JWT_SECKRET_KEY'))
}

const EmployeeModel=model('Employee',employeeSchema)

module.exports=EmployeeModel



Enter fullscreen mode Exit fullscreen mode

In above schema i have define multiple fields like unique fields and referenced fields of Company Model.WorksWith is like forein Key of mongodb if any changes of the field it automatcally reflect its properties.

route.js

var express = require('express');
const router = express.Router();
const validateEmployee=require('../validations/employee.validate')
const employeeController=require('../controllers/employee.controller')

router.get('/:id');

router.post('/signup',validateEmployee,employeeController.employeeSignUp);

module.exports = router;
Enter fullscreen mode Exit fullscreen mode

validation.js

const Joi=require('joi')

module.exports=(req,res,next)=>{
    try {
        const empSchema=Joi.object({
            fullName:Joi.string().min(3).max(64).required().label("Full Name"),
            email:Joi.string().email().required().label("Email Address"),
            password:Joi.string().min(5).max(10).required().label("Password"),
            phone:Joi.string().min(10).max(12).required().label("Phone")
        })
        const {error}=empSchema.validate(req.body);
        if(error){
            return res.status(400).send(error.details[0].message)
        }
        console.log(res);
        next()
    } catch (err) {
        next(err)
    }
}
Enter fullscreen mode Exit fullscreen mode

controller.js

const EmployeeModel=require('../models/employee.model')
const hashPassword=require('../services/hashPassword')
const generateEmployeeID=require('../services/generateEmployeeID')


module.exports.employeeSignUp=async (req,res,next)=>{
    try {
        const {fullName,email,phone,password}=req.body

        const oldEmployee=await EmployeeModel.findOne({$or:[{email},{phone}]})
        if(oldEmployee){
           return res.status(409).send("Employee already Exist")
        }
        const hashPass=await hashPassword(password);
        const userID=generateEmployeeID(email,phone)
        const employee=new EmployeeModel({fullName,email,phone,password:hashPass,userID})
        const empToken=employee.generateEmployeeToken()
        const result=await employee.save()
        if(result){
            res.status(200).header('emp-token',empToken).send(result)
        }else{
            res.status(400).send("Signup Failed")
        }
    } catch (err) {
        next(err)
    }
}
Enter fullscreen mode Exit fullscreen mode

In this Code only we can understand how we can make better schema
many cases like we only some value it on field we can make a enum like this.

gender:{
    type:String,
    enum:['male','female'],
    required:true
}
Enter fullscreen mode Exit fullscreen mode

above only two value accepted male or female not any other string accepted by mongo Schema. Thank You Everyone.

Discussion (0)