MongoDB Complex Schemas Structures
Tags: mongodb, database, node, javascript
Published: 2022-02-26 04:28:17

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



```
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;
```

## 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)
    }
}
```

## 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)
    }
}
```

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
}
```
above only two value accepted male or female not any other string accepted by mongo Schema. Thank You Everyone.