How to generate auto increment count field using Mongodb Schema - mongodb

I have a database related to the interview process which consists of multiple fields.
basically, there are 5 APIs
POST - (Candidate info) - for entering candidate data
PATCH - for updating candidate info
PATCH - (for Short Listing and reviewing) - updates in existing candidate
PATCH - (for Scheduling the candidate interview) - entering the interview field which is an array object.
GET Method
I want auto increment for the count field under Interview Round Count
whenever the PATCH Method is updated for the same candidate (data updated successfully)
How can I do that in Mongodb
Complete Schema:
const mongoose = require('mongoose');
const mongoosePaginate = require('mongoose-paginate-v2');
const { Schema } = mongoose;
const { EMAIL } = require('../../config/patterns.js');
const InterviewSchema = new Schema(
{
firstName: {
type: String,
required: true,
trim: true,
maxlength: 30,
},
lastName: {
type: String,
trim: true,
maxlength: 30,
},
email: {
type: String,
required: true,
trim: true,
match: EMAIL,
},
gender: {
type: String,
required: true,
enum: ['male', 'female', 'other'],
},
contactNumber: {
type: Number,
unique: true,
required: true,
},
alternateContactNumber: {
type: Number,
},
resume: {
type: String,
required: true,
},
designation: {
type: String,
required: true,
enum: ['trainee', 'se', 'sse', 'tl', 'systemEngineer'],
},
profile: {
type: String,
required: true,
enum: [
'react',
'reactNative',
'node',
'fullstack',
'php',
'ios',
'android',
'python',
],
},
experience: {
years: {
type: Number,
required: true,
},
months: {
type: Number,
required: true,
},
},
ctc: {
current: {
type: Number,
required: [true, 'In LPA'],
},
expected: {
type: Number,
required: [true, 'In LPA'],
},
offered: {
type: Number,
required: [true, 'In LPA'],
},
},
noticePeriod: {
type: Number,
default: 0,
},
referrer: {
type: {
type: String,
enum: ['consultant', 'employee', 'website', 'social'],
},
name: {
type: String,
trim: true,
required: true,
},
},
status: {
type: String,
enum: [
'shortlisting',
'shortlisted',
'interviewing',
'selected',
'rejected',
'onHold',
'denied',
'offerSent',
'joined',
'cancel',
],
},
// Shortling the Candidate - PATCH Method
reviewer: {
name: {
type: String,
trim: true,
required: true,
},
email: {
type: String,
trim: true,
required: true,
},
id: {
type: Number,
required: true,
},
},
date: {
type: Date,
default: Date.now,
},
// Scheduling the interview (this can be repeated no.of times for the interview round)
// represented in Array object
interview: [
{
interviewerName: {
type: String,
trim: true,
},
date: {
type: Date,
default: Date.now,
},
mode: {
type: String,
enum: ['telephonic', 'video', 'f2f'],
default: 'telephonic',
},
meeting: {
link: {
type: String,
trim: true,
},
platform: {
type: String,
trim: true,
},
},
round: {
count: { // want auto-increment count
type: Number,
},
type: {
type: String,
enum: ['written', 'technical', 'hr'],
},
},
interviewStatus: {
type: String,
enum: ['rejected', 'onHold', 'selected', 'schedule'],
},
feedback: {
technical: {
type: Number,
required: true,
min: 1,
max: 5,
},
logical: {
type: Number,
required: true,
min: 1,
max: 5,
},
communication: {
type: Number,
required: true,
min: 1,
max: 5,
},
comment: {
type: String,
min: 10,
max: 200,
},
},
recommendation: {
type: String,
enum: ['yes', 'no'],
},
},
],
},
{
timestamps: true,
},
);
InterviewSchema.plugin(mongoosePaginate);
const InterviewProcess = mongoose.model('interviewprocess', InterviewSchema);
module.exports = InterviewProcess;

Related

How to store range(in geocircle radius form) in mongoose schema

I am building an e-commerce application. Every store has a delivery range so i want to set delivery range of every store in the database to show the store only to those who falls in the delivery range.
Store Schema.
const mongoose = require("mongoose");
const sellerSchema = new mongoose.Schema({
name:{
type: String,
required: true,
},
type: {
type: String,
required: true
},
location: {
type: {
type: "String",
enum:['Point']
},
coordinates: {
type: [Number],
index: '2dsphere'
}
},
owner: {
type: String,
required: true
},
items: [{
type: mongoose.Schema.Types.ObjectId,
ref: "items"
}],
contact: {
type: String,
required: true
},
loginId: {
index:true,
unique: true,
type: String,
},
password: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
}
});
const sellerModel = mongoose.model("sellers",sellerSchema);
module.exports = sellerModel;

How to push an item to a nested array?

I am trying to make an api with express.js and mongoDB (using mongoose) and don't know how to properly add an item to my existing array (nextUp). For example I have an existing User in my database with templates: { issues: { nextUp: [], inProgress: [], completed: [] } } and want to add e.g. {issueName: 'MyName', issueDate: '20/5/2020'} to nextUp field.
const mongoose = require('mongoose');
const { Schema } = mongoose;
const UserSchema = new Schema({
username: {
type: String,
required: true,
unique: true,
minlength: 3,
sparse: true,
},
email: {
type: String,
required: true,
unique: true,
minlength: 5,
maxlength: 255,
sparse: true,
},
password: {
type: String,
required: true,
minlength: 8,
sparse: true,
},
newsletterSubscribed: {
type: Boolean,
},
termsAndPolicyAgreement: {
type: Boolean,
required: true,
},
templates: {
title: {
type: String,
},
description: {
type: String,
},
issues: {
nextUp: [
{
issueName: {
type: String,
},
issueDate: {
type: String,
},
},
],
inProgress: [
{
issueName: {
type: String,
},
issueDate: {
type: String,
},
},
],
completed: [
{
issueName: {
type: String,
},
issueDate: {
type: String,
},
},
],
},
},
});
const UserModel = mongoose.model('user', UserSchema);
module.exports = UserModel;
I've tried to do that but my item hasn't added. (username Kacper exists there is no problem with that).
UserModel.findOneAndUpdate(
{ username: 'Kacper' },
{
$push: {
nextUp: [
{
issueName: 'MY NEW ISSUE',
issueDate: 'MY ISSUE DATE',
},
],
},
},
);

Mongoose - Validate ObjectID related document

I need to validate as required a field "product" in Model Event. Product is ObjectID reference to Product Model.
I tried with this 2 approaches, but it is not validating
product: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Product',
required: true
}]
},
product: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Product',
required: function () {
return this.product.length > 0
},
}]
},
The Event is being created anyway, and when I add no products, field product is an empty array.
Any idea how can I validate it?
Models:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Product = require('../models/Product');
const moment = require('moment');
const EventSchema = new Schema({
client: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Client'
}]
},
product: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Product',
required: true
}]
},
date: {
type: Date,
maxlength: 64,
lowercase: true,
trim: true
},
place: {
type: String,
maxlength: 1200,
minlength: 1,
},
price: {
type: Number
},
comment: {
type: String,
maxlength: 12000,
minlength: 1,
},
status: {
type: Number,
min: 0,
max: 1,
default: 0,
validate: {
validator: Number.isInteger,
message: '{VALUE} is not an integer value'
}
},
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true }
},
{
timestamps: true
},
);
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const Provider = require('./Provider')
const ProductSchema = new Schema({
name: {
type: String,
maxlength: 64,
minlength: 1,
required: [true, 'Product name is required'],
},
brand: {
type: String,
maxlength: 64,
minlength: 1,
},
description: {
type: String,
maxlength: 12000,
min: 1,
},
comment: {
type: String,
maxlength: 12000,
minlength: 1
},
state: {
type: String,
maxlength: 64,
minlength: 0
},
disponible: {
type: Boolean,
default: true
},
price: {
type: Number,
default: 0,
min: 0,
max: 999999
},
provider: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Provider'
}]
},
category: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Category'
}]
},
event: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Event'
}]
},
image: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Image'
}]
},
},
{
toObject: { virtuals: true },
toJSON: { virtuals: true }
},
{
timestamps: true
});
You can use custom validators feature of mongoose.
If the validator function returns undefined or a truthy value, validation succeeds. If it returns falsy (except undefined) or throws an error, validation fails.
product: {
type: [
{
type: Schema.Types.ObjectId,
ref: "Product",
required: true
}
],
validate: {
validator: function(v) {
return v !== null && v.length > 0;
},
message: props => "product is null or empty"
}
}
Now when you don't send product field, or send it empty array it will give validation error.
const notEmpty = function(users){
if(users.length === 0){return false}
else { return true }
}
const EventSchema = new Schema({
product: {
type: [{
type: Schema.Types.ObjectId,
ref: 'Product',
required: true,
validate: [notEmpty, 'Please add at least one']
}]
}
})

MongoDB/Mongoose Schema for checking room availability

I've following schema for a Hotel room.
const { Schema, model } = require('mongoose');
const reservationSchema = new Schema({
checkIn: {
type: Date,
require: true
},
checkOut: {
type: Date,
require: true
},
status: {
type: String,
require: true,
enum: ['pending', 'cancel', 'approved', 'active', 'completed']
}
});
const roomSchema = new Schema(
{
title: {
type: String,
required: true
},
slug: {
type: String
},
description: {
type: String,
required: true
},
capacity: {
adults: {
type: Number,
required: true
},
childs: {
type: Number,
default: 0
}
},
roomPrice: {
type: Number,
required: true
},
gallery: [
{
type: String,
require: true
}
],
featuredImage: {
type: String,
require: true
},
reservations: [reservationSchema],
isAvailable: {
type: Boolean,
default: true
},
isFeatured: {
type: Boolean,
default: false
},
isPublish: {
type: Boolean,
default: false
}
},
{ timestamps: true }
);
module.exports = model('Room', roomSchema);
Now I want to find rooms which are not reserved for a particular date period.
Example: If the search query is checkIn: 12/25/2019 and checkOut:12/30/2019 then the query result will show that rooms which are not reserved for this period. Also, it will show the reserved room if the reservation status is canceled.
How can I achieve this?
Do I need to change the Schema design for achieving this?

Push a sub-subdocument on a Mongoose Schema [duplicate]

This question already has answers here:
Mongodb $push in nested array
(4 answers)
Closed 3 years ago.
Consider these 3 schemas and hierarchy: A Project has multiple Stages, a Stage has multiple Events.
For pushing a new Stage into a Project, I do this:
Project.findOneAndUpdate(
{ slug: projectSlug },
{ $push: { stages: myNewStage } },
).then((post) => res.status(201).json({
message: 'stage created successfully',
data: post,
})).catch((error) => {
return res.status(500).json({
code: 'SERVER_ERROR',
description: 'something went wrong, Please try again',
});
});
But, how can I push a new event into a Stage? As far as I've seen, a subdocument does not have the same properties as a document (such as find, findAndUpdate).
My actual schemas:
PROJECT SCHEMA
const mongoose = require('mongoose');
const Stage = require('./Stages').model('Stages').schema;
const projectSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
description: {
type: String,
},
slug: {
type: String,
trim: true,
required: true,
lowercase: true,
unique: true,
},
clientSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
stages: [Stage],
startDate: {
type: Date,
trim: true,
required: true,
},
endDate: {
type: Date,
trim: true,
required: false,
},
},
{
timestamps: true,
});
module.exports = mongoose.model('Projects', projectSchema);
STAGE SCHEMA
const mongoose = require('mongoose');
const Event = require('./Events').model('Events').schema;
const stageSchema = new mongoose.Schema({
name: {
type: String,
required: true,
},
description: {
type: String,
},
slug: {
type: String,
trim: true,
required: true,
lowercase: true,
unique: true,
},
clientSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
projectSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
events: [Event],
},
{
timestamps: true,
});
module.exports = mongoose.model('Stages', stageSchema);
EVENT SCHEMA
const mongoose = require('mongoose');
const Comment = require('./Comments').model('Comments').schema;
const eventSchema = new mongoose.Schema({
_id: {
type: String,
trim: true,
lowercase: true,
},
userEmail: {
type: String,
trim: true,
required: true,
lowercase: true,
},
text: {
type: String,
},
imgUrl: {
type: String,
},
documentUrl: {
type: String,
},
stageSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
clientSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
projectSlug: {
type: String,
trim: true,
required: true,
lowercase: true,
},
comments: [Comment],
},
{
timestamps: true,
});
module.exports = mongoose.model('Events', eventSchema);
To push a new event into your stages array given that you have the projectSlug and stageSlug, you can do this:
Project.findOneAndUpdate(
{
$and: [
{ slug: projectSlug },
{ 'stages.slug': stageSlug },
]
},
{
$push: { 'stages.$.events': newEvent }
}
)
.then(() => {})
.catch(() => {});