How to UPDATE on Child, the reference of Parent upon Parent deletion? - javascript

I'm making this question since I'm having a hard time asking the right question when I research. I hope to be clear:
I've got 2 Schemas:
Parent [TEAM]:
const EquipaSchema = new mongoose.Schema({
trab1: {
type: Schema.Types.ObjectId,
required: true,
ref: 'Trab'
},
trab2: {
type: Schema.Types.ObjectId,
required: true,
ref: 'Trab'
},
trab3: {
type: Schema.Types.ObjectId,
required: true,
ref: 'Trab'
},
teamName: {
type: String,
required: true
},
marcsEquipa: [{
type: Schema.Types.ObjectId,
ref: 'Marcacao'
}]
},
{collection: 'Equipas'})
And Child [Project]:
const MarcacaoSchema = new mongoose.Schema({
name: { type: String, required: true },
email: { type: String, required: true },
date: { type: Date, required: true},
hour: { type: String, required: true},
type: { type: String, required: true},
address: {type: String, required: true},
state: {type: String, default: 'Pendente'},
// equipa: { type: Schema.Types.ObjectId, ref: 'Equipa' },
equipa: {
type: String,
default: 'Não'
},
cliente: {
type: Schema.Types.ObjectId,
ref: 'User'
},
aval_admin: {
type: String,
default: "Sem Avaliação pelo Manager"
},
descricao: {
type: String,
default: "Sem Descrição"
},
aval_client: {
type: String,
default: "Sem Avaliação do Cliente"
},
avaliado: {
type: Boolean,
default: false
},
team: {
type: Schema.Types.ObjectId,
ref: 'Equipas'
}
},
{collection: 'Marcacao'}
My goal is: When a team is deleted, all of the projects in the team array ['marcsEquipa[]'] get updated to {team: null}, so that I can assign a NEW team to the SAME project.
I've tried using middlewares, but some of its usages are now deprecated and had no success. Whats the correct way to solving this problem?
Thank you in advance

await Marcacao.updateMany({team: req.params._id}, {team: null});
This was the solution. Where req.params._id is the team ID.

Related

how to compare document from 3 different collections

I have three collections named employees, leaves, events in my mongodb database. I want to fetch employees who are not on vacation nor have an event scheduled on a specific date.
employees Model
const employeeSchema = new mongoose.Schema({
name: { type: String, required: true },
role: {
type: String,
required: true,
},
image: { type: String, required: false },
phoneNumber: {
type: Number,
required: true,
},
email: {
type: String,
default: null,
required: \[true, "Email is required"\],
},
empType: {
type: String,
required: true,
},
password: { type: String, required: true },
lastLogin: { type: Date, default: null },
token: { type: String, default: null },
deviceId: { type: Array, default: null },
});
Events model
const eventsSchema = new mongoose.Schema({
venue: { type: String, required: true },
eventType: { type: String, required: true },
eventDate: { type: Date, required: true },
startTime: { type: Date, required: true },
departureTime: { type: Date, required: true },
numberOfCameras: { type: Number, required: true },
numberOfDays: { type: Number, required: true },
packagePrice: { type: Number, required: true },
teamLead: { type: String, required: true },
teamList: { type: Array, required: true },
teamMembers: [],
});
leaves model
userId: { type: mongoose.ObjectId, required: true },
startDate: { type: Date, required: true },
endDate: { type: Date, required: true },
reason: { type: String, required: true },
leaveSeekerName: { type: String, required: true },
leaveSeekerRole: { type: String, required: true },
status: { type: String, default: "pending" },
},
{
timestamps: true,
}
so i am want to get employee who are not on leave nor assigned an event on specified date
The question is not completed.
First, you should complete the linked relationship among the 3 tables.
If your 3 schemas use _id in employees and teamMember of events, userId in leaves to tag someone as the same person on the below.
const employeeSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
role: {
type: String,
required: true,
},
image: {
type: String,
required: false
},
phoneNumber: {
type: Number,
required: true,
},
email: {
type: String,
default: null,
required:true,
},
empType: {
type: String,
required: true,
},
password: {
type: String,
required: true
},
lastLogin: {
type: Date,
default: null
},
token: {
type: String,
default: null
},
deviceId: {
type: Array,
default: null
},
});
const eventsSchema = new mongoose.Schema({
venue: {
type: String,
required: true
},
eventType: {
type: String,
required: true
},
eventDate: {
type: Date,
required: true
},
startTime: {
type: Date,
required: true
},
departureTime: {
type: Date,
required: true
},
numberOfCameras: {
type: Number,
required: true
},
numberOfDays: {
type: Number,
required: true
},
packagePrice: {
type: Number,
required: true
},
teamLead: {
type: String,
required: true
},
teamList: {
type: Array,
required: true
},
teamMembers: [
{
_id:mongoose.ObjectId,
name: String,
}
],
});
const leaveSchema = new mongoose.Schema({
userId: {
type: mongoose.ObjectId,
required: true
},
startDate: {
type: Date,
required: true
},
endDate: {
type: Date,
required: true
},
reason: {
type: String,
required: true
},
leaveSeekerName: {
type: String,
required: true
},
leaveSeekerRole: {
type: String,
required: true
},
status: {
type: String,
default: "pending"
},
}, {
timestamps: true,
})
You can consider use aggregations like this:
db.employees.aggregate( [
{
"$lookup": {
"from": "events",
"localField": "teamMembers._id",
"foreignField": "_id",
"as": "events"
}
},
{
"$lookup": {
"from": "leaves",
"localField": "_id",
"foreignField": "userId",
"as": "leaves"
}
},
{
"$match": {
"$and": [
{
"events.startTime": {
"$lte": nowTime
},
"events.departureTime": {
"$gte": nowTime
},
"leves.startDate": {
"$lte": nowDate
},
"leaves.endDate": {
"$gte": nowDate
}
}
]
}
}
] )
You may need to adjust the value of nowTime and nowDate.

MongoDB (mongoose) filter with value in array with reference

I am trying to filter an array in a document in mongoose.
The problem i am having is trying to filter with a value in the array that is in the reference.
To clarify, i have a document containg all the information about a course. In that course i have a array of objects that contains information about students. An object containts a status and also a refrence to the actual user object. I would like filter the students array with a value found in the refrence.
The way i have tested this is as following:
courseModel.findOne({ _id: courseId, 'students.user.startDate': { $lte: startDate } });
My models look like this:
CourseModel:
{
name: {
type: String,
required: true,
maxlength: 50,
minlength: 2,
trim: true
},
description: {
type: String,
required: false,
maxlength: 500,
trim: true
},
type: {
type: String,
required: true,
enum: ['physical', 'online', 'quiz']
},
color: {
type: String,
required: true,
match: /^#([A-Fa-f0-9]{6}|[A-Fa-f0-9]{3})$/
},
events: [
{
type: Schema.Types.ObjectId,
ref: 'event'
}
],
questions: [
{
type: Schema.Types.ObjectId,
ref: 'question'
}
],
educators: [
{
type: Schema.Types.ObjectId,
ref: 'user'
}
],
students: [
{
user: {
type: Schema.Types.ObjectId,
ref: 'user'
},
status: {
type: String,
enum: ['notBooked', 'booked', 'attended', 'completed']
},
lastSlackMessage: {
ts: {
type: String
},
channel: {
type: String
}
},
events: [
{
type: Schema.Types.ObjectId,
ref: 'event'
}
]
}
],
teams: [
{
type: Schema.Types.ObjectId,
ref: 'team'
}
],
createdBy: {
type: Schema.Types.ObjectId,
ref: 'user'
},
updatedBy: {
type: Schema.Types.ObjectId,
ref: 'user'
}
}
UserModel:
{
name: {
type: String,
required: true,
maxlength: 100,
trim: true
},
email: {
type: String,
required: true,
minlength: 5,
match: /^(([^<>()[\]\\.,;:\s#"]+(\.[^<>()[\]\\.,;:\s#"]+)*)|(".+"))#((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/
},
employeeId: {
type: String,
required: true
},
slackId: {
type: String,
default: ''
},
teams: [
{
type: Schema.Types.ObjectId,
ref: 'team'
}
],
questions: [
{
question: {
type: Schema.Types.ObjectId,
ref: 'question'
},
status: {
type: String,
enum: ['answered', 'pending', 'notSent']
},
tries: {
type: Number,
default: 0
}
}
],
startDate: {
type: Date,
required: true
}
}
I appreciate any help i can get, thank you!

How to populate infinitley comment reply mongoose model

I have added a reply on post comments on my website and now I have a problem how to populate deep reply. I always use this method .populate('comments.authorid', ['username', 'avatarUrl']) but when the user reply on reply, there is a problem.
Do you have any idea how to solve it? I'm looking for something that allows populate all fields by name
Update!
Ok I have found the problem. So in the commentSchema I use comments:[this] It does not work. I need a way to nest CommentSchema in comments field.
const CommentSchema = new Schema({
authorid: {
type: mongoose.Schema.Types.ObjectId,
ref: "Users",
required: true,
},
Date: {
type: Date,
default: Date.now
},
body: {
type: String,
required: true,
minlength: 1,
},
comments:[this],
like:[{
user:{
type: mongoose.Schema.Types.ObjectId,
ref: "Users",
}
}]
});
const userPost = new Schema ({
body: {
type: String,
required: true,
text: true,
minlength: 4,
},
file:{
type: String
},
postTags: [{
type: String
}],
authorid: {
type: mongoose.Schema.Types.ObjectId,
ref: "Users",
required: true,
},
Date:{
type: Date,
default: Date.now
},
like:[{
user:{
type: mongoose.Schema.Types.ObjectId,
ref: "Users",
}
}],
comments: [
CommentSchema.schema
],
});

Ignore key if empty value

I'm creating a mongoose entry, and this is my schema:
const OrdersSchema = new mongoose.Schema({
user: {
type: mongoose.Schema.Types.ObjectId,
ref: "Users",
required: true,
},
currency: {
type: String,
required: true,
},
country: {
type: String,
required: true,
},
rate: {
type: Number,
required: true,
},
amount: {
type: Number,
required: true,
},
coupon: {
type: mongoose.Schema.Types.ObjectId,
ref: "Coupons",
},
subtotal: {
type: Number,
required: true,
},
total: {
type: Number,
required: true,
},
recipient: {
type: mongoose.Schema.Types.ObjectId,
required: true,
},
status: {
type: String,
required: true,
default: "On-hold",
},
payment: {
type: Object,
required: true,
},
shortId: {
type: String,
required: true,
},
createdAt: {
type: Date,
default: Date.now,
required: true,
},
});
Coupon is optional. The code to create a new order is:
const order = await Orders.create({
user: req.id,
currency: body.selectedCountry,
country: body.selectedCountry,
rate: rate.rates[body.selectedCountry],
amount: body.amount,
coupon: body.coupon.code,
subtotal: body.subtotal,
total: body.total,
recipient: body.recipient,
payment: body.paymentData,
shortId: shortid.generate(),
});
However, when coupon is an empty string I get a MongooseError [CastError]: Cast to ObjectID failed for value "" at path "coupon"
I need to remove this key and value from the object creation, when creating the order.
How can I remove this key if coupon code is empty?
Thanks in advance
The issue is you are trying to fit an empty string value in the data-type objectID.
A possible solution to this is to use below condition in your code:
coupon: body.coupon.code ? body.coupon.code : null
This will set coupon to null in case body.coupon.code is "".

ExpressJS - duplicate key error collection

I have problem with this error when I am creating a new event with category which exists in my database, for example I created an event with category "javascript" and save it to db, and then i tried to create a new event with categories "javascript, html, css" and then i got this error duplicate key error collection
So my schema for event is this:
const EventSchema = new Schema({
title: {
type: String,
required: true,
min: 3,
max: 100
},
featuredImage: {
type: Object,
},
from: {
type: Date,
required: true
},
to: {
type: Date,
required: true
},
location: {
name: {
type: String
},
address: {
type: Object
}
},
description: {
type: String
},
categories: {
type: Array,
trim: true
},
featured: {
type: Boolean
},
created_by: {
type: Schema.Types.ObjectId,
ref: 'User'
},
slug: {
type: String,
default: null
},
registration: {
type: Boolean
},
tickets: [],
allday: {
type: Boolean
},
speakers: [{
type: Schema.Types.ObjectId,
ref: 'User'
}],
attendees: [{
type: Schema.Types.ObjectId,
ref: 'User'
}],
comments: [CommentSchema]
}, {
timestamps: true,
usePushEach: true
});
So basically sending array of strings and i got this error.
You probably have some index defined on categories with the unique flag.
You can list the existing indexes with db.events.getIndexes().
You could drop and recreate the culprit (be careful):
> db.events.dropIndex({categories:1})
> db.events.ensureIndex({categories:1},{sparse:true})

Categories