mongoose find and update nested object in an array - node.js

Below is my mongoose schema.
An application can have multiple incidents and subscribers. Each incident can have multiple journal updates.
Application->incident(s)->journalupdate(s)
My goal is to allow users to update an incident detail in an application. Later add a journal update to an incident in the application.
const JournalUpdateSchema = mongoose.Schema({
timeStamp: { type: Date, required: true },
owner: { type: String },
updateText: { type: String }
});
// Incident Schema
const IncidentSchema = mongoose.Schema({
incidentNum: { type: String, required: true },
incidentPriority: { type: String, required: true },
description: { type: String, required: true },
jounralUpdates: [JournalUpdateSchema]
});
//Subscriber Schema
const SubscriberSchema = mongoose.Schema({
subscriberName: { type: String },
subscriberMail: { type: String },
subscriberPhone: { type: String }
});
// Application Schema
const ApplicationSchema = mongoose.Schema({
applicationName: { type: String, required: true },
clusterName: { type: String, required: true },
ragStatus: { type: String, required: true },
incidents: [IncidentSchema],
subscribers: [SubscriberSchema]
});
I have already tried Applications.Update(), Applications.findByIdAndUpdate() methods but I cannot reach the incident level to update.
can someone help me with this please? Any help is greatly appreciated.
Thanks.

Related

Mongoose Query is not fetching match data from multiple table

I am using nodejs,mongodb and mongoose. This query is not fetching match data from user and order table. I have read mongoose docs and alot of other articeles. It's according to it but doesn't fetch match data from tables.
Query code:
const data = await order
.find({ admin_id: req.params.id })
.populate("orderRelate");
console.log(data);
My user and order schema code is:
const mongoose = require("mongoose");
const UserSchema = new mongoose.Schema(
{
username: { type: String, required: true, unique: true },
email: { type: String, required: true, unique: true },
password: { type: String, required: true },
mobile_no: { type: Number, required: true },
profilePic: { type: String, defaut: "" },
owner: { type: Boolean, defaut: false },
},
{ timestamps: true }
);
const orderSchema = new mongoose.Schema(
{
customer_id: { type: String, required: true },
admin_id: { type: String, required: true },
order_type: { type: String, defaut: "normal" },
order_status: { type: String, required: true },
order_price: { type: Number, required: true },
order_address: { type: String, required: true },
order_pickDate: { type: String, required: true },
order_pickTime: { type: String, required: true },
orderRelate: [{ type: mongoose.Schema.Types.ObjectId, ref: "User" }],
},
{ timestamps: true }
);
module.exports = mongoose.model("User", UserSchema);
module.exports = mongoose.model("Order", orderSchema);
Please let me know if anyone know why I am facing this issue.
Thanks
Please try with findById maybe it's work
i don't know how you wrote your middleware function but..
await Order.find({orderRelate: req.user.id})

How to update a nested array in mongoose?

I am new to the backend and trying to learn by building some stuff but unfortunately, I got stuck.
I want to know if I can update a nested array of objects in Users Schema using Mongoose in an efficient and elegant way.
Users Schema:
const mongoose = require('mongoose');
const Schema = mongoose.Schema;
const UserSchema = new Schema({
name: {
type: String,
required: true
},
username: {
type: String,
required: true,
unique: true
},
email: {
type: String,
required: true,
unique: true
},
gender: {
type: String,
required: true
},
password: {
type: String,
required: true
},
friends: [{}],
notifications: []
}, {timestamps: true});
module.exports = User = mongoose.model('user', UserSchema);
In the friends' field, I stored friend request with the status of pending
I want if the user whose the request was sent to, hits an endpoint, to accept the request
by changing the status from pending to success.
This is how a friend request was stored:
friendRequest = {
_id: req.user.id,
status: 'pending',
sentByMe: false,
new: true,
inbox: []
}
Thanks as you help me out!!! 🙏🙏🙏
You should first create an additional friendRequest and inbox schemas like this:
var mongoose = require('mongoose');
var Schema = mongoose.Schema;
const InboxSchema = new Schema({
user_id: {
type: String,
required: true
},
from_id: {
type: String,
required: true
},
message: {
type: String,
required: true
},
the_date_time: {
type: Date,
required: true
}
});
mongoose.model('Inbox', InboxSchema);
const FriendRequestSchema = new Schema({
user_id: {
type: String,
required: true
},
status: {
type: String,
required: true
},
sentByMe: {
type: Boolean,
required: true,
unique: true
},
inbox: [InboxSchema]
})
mongoose.model('FriendRequests', FriendRequestSchema);
and update your Users schema:
const UserSchema = new Schema({
name: {
type: String,
required: true
},
username: {
type: String,
required: true,
unique: true
},
email: {
type: String,
required: true,
unique: true
},
gender: {
type: String,
required: true
},
password: {
type: String,
required: true
},
friends: [FriendSchema],
notifications: [FriendRequestSchema]
}, {timestamps: true});
And then use the friendRequest object
friendRequest = {
_id: req.user.id,
status: 'pending',
sentByMe: false,
new: true,
inbox: []
}
to update the Users collection
Users.update({ _id: user_id }, { $push: { notifications: friendRequest } });
Whenever you have arrays of objects within collections, its best to define additional schemas. You should also consider adding indexes to your collection schemas.
Update:
A FriendSchema would look like this:
const FriendsSchema = new Schema({
friend_id: {
type: String,
required: true
},
friend_name: {
type: String,
required: true
},
friendship_made: {
type: Date,
required: true
}
// you have to define FriendSchema before you define Users since you
// now reference [FriendSchema] in UserSchema
mongoose.model('Friends', FriendSchema);
And so is personA friends with personB?
Users.findOne({ "_id": personA.id, "friends.friend_id": personB.id});

Populate returns whole parent document

I just started learning express and mongodb. I recently faced the kind of problem, I'm trying to select all the subdocuments which are inside of Room model.
const books = await Room.find().populate('book');
But it returns whole room document when i want to select only bookings field.
Here's the book schema
const bookSchema = new mongoose.Schema({
startDate: {
type: Date,
required: true,
},
endDate: {
type: Date,
required: true,
},
name: {
type: String,
required: true,
},
phone: {
type: String,
required: true,
},
});
module.exports = mongoose.model("book", bookSchema)
And here's the room schema
const roomSchema = new mongoose.Schema({
currentlyReserved: {
type: Boolean,
default: false,
},
people: {
type: Number,
required: true,
},
roomNumber: {
type: Number,
required: true,
},
pricePerPerson: {
type: Number,
required: true,
},
reservedUntil: {
type: Date,
default: null,
},
reservedBy: {
type: String,
default: null,
},
bookings: {
type: [{ type: mongoose.Schema.Types.ObjectId, ref: "book" }],
},
});
module.exports = mongoose.model("room", roomSchema);
You can project with with second arg to find().
https://docs.mongodb.com/manual/reference/method/db.collection.find/#projection
const books = await Room.find({}, {bookings: 1}).populate('bookings');

How to handle normalization on mongoDB collections?

There are two collections Employee and 'Project', It need to maintain history of project allocations for employee as well as projects basis.
I have created collection schema but it duplicates the data, is there any other way I can achieve this?
Employee Schema
const employeeSchema = mongoose.Schema({
name: {
type: String,
required: true
},
project: {
start: {
type: Date,
required: true
},
end: {
type: Date,
required: true
},
project: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Project',
required: true
}
},
}
Project Schema
const projectSchema = new mongoose.Schema({
name: {
type: String,
required: true
},
employee: {
start: {
type: Date,
required: true
},
end: {
type: Date,
required: true
},
project: {
type: mongoose.Schema.Types.ObjectId,
ref: 'Employee'
}
}
});
Or Can I create separate collection for mapping both project and employee? if I do this then what is the difference between MongoDB and RDBMS?

one to many relationship in mongoose

I'm using mean stack to create a hybrid app.I'm using nosql to create DB in mongoose.My DB consists of two tables one is 'donors' and another one is 'bloodGroup'.
My 'bloodGroup' schema is as follows:
module.exports = function(mongoose) {
var Schema = mongoose.Schema;
/* bloodGroup Schema */
var bloodGroupSchema = new Schema({
name: { type: String, required: true }
});
}
My 'Donor'schema is as follows:
/* Donor Schema */
var DonorSchema = new Schema({
Name: { type: String, required: true },
DOB: { type: Date, required: true, trim: true },
Sex: { type: String },
BloodGroupID: { type: Schema.Types.ObjectId, ref: 'BloodGroup', required: true },
ContactNo: { type: String, required: true },
LocationId: { type: Schema.Types.ObjectId, ref: 'Location', required:true },
EmailId: { type: String, required: true },
Password: { type: String, required: true }
});
When many donors refer to a single blood group then BloodGroup object Id error is reported.How to solve this problem?
You can refer this link for documentation: http://mongoosejs.com/docs/populate.html
Saving Refs
/* Donor Schema */
var DonorSchema = new Schema({
_id : {type: Number},
Name: { type: String, required: true },
DOB: { type: Date, required: true, trim: true },
Sex: { type: String },
BloodGroupID: { type: Schema.Types.ObjectId, ref: 'BloodGroup', required: true },
ContactNo: { type: String, required: true },
LocationId: { type: Schema.Types.ObjectId, ref: 'Location', required:true },
EmailId: { type: String, required: true },
Password: { type: String, required: true }
});
/* bloodGroup Schema */
var bloodGroupSchema = new Schema({
_bid :{ type: Number, ref: 'Donor' },
name: { type: String, required: true }
});
module.exports = mongoose.model('Donor', DonorSchema);
module.exports = mongoose.model('Blood', bloodGroupSchema);
var vidya = new Donor({ _id: 0, name: 'Vidya', sex: 'F' });
vidya.save(function (err) {
if (err) return handleError(err);
var blood = new BloodGroup({
name: 'B+',
_bid: vidya._id // assign the _id from the Donor
});
blood.save(function (err) {
if (err) return handleError(err);
// thats it!
});
});
Mongo is not a Relational database, relation one to many does not exist in mongDB. The question is quite confusing, but following the title, you should either embed the donnors into the BloodGroup, or create an Id field unique to which you will refer and do two queries.

Resources