Reputation: 1283
Say i have a document that looks like this:
{
"personId": 13998272,
"address": [
{
"addressType": "HOME",
"streetNo": 21,
"addressLine1": "LORRAINE AVENUE",
"addressLine2": "EDGEWATER",
"city": "KINGSTON",
"parish": "ST ANDREW",
"country": "JAMAICA",
"qScore": 0.9,
"modifiedDate": "2019-02-17 15:24:19"
}
],
"phone": [
{
"originalNumber": "+18767842983",
"phoneNumberIFormat": "+18768514679",
"phoneNumberLFormat": "8768514679",
"qualityScore": 0.8,
"dataSource": "PERSON",
"modifiedDate": "2018-12-17 09:42:31"
}
],
"email": [
{
"emailAddress": "[email protected]",
"dataSource": "FINACLE",
"qualityScore": 0.89,
"modifiedDate": "2018-12-17 09:38:41"
}
]
}
My schema is defined in the code snippet below for reference:
const contactSchema = new mongoose.Schema({
pid: Number,
address: [
new mongoose.Schema({
addressType: String,
streetNo: String,
addressLine1: String,
addressLine2: String,
city: String,
parish: String,
country: String,
qScore: String,
modifiedDate: String
})
],
phone: [
new mongoose.Schema({
originalNumber: String,
phoneNumberIFormat: String,
phoneNumberLFormat: String,
qualityScore: Number,
dataSource: String,
modifiedDate: String
})
],
email: [
new mongoose.Schema({
emailAddress: String,
dataSource: String,
qualityScore: Number,
modifiedDate: String
})
]
});
How would update each array of embedded documents without overwriting the others?
Say a request is with and address and email object but not phone, how would I handle that?
Upvotes: 3
Views: 74
Reputation: 421
You can try this ..
Get the structure of the contact object then the check to see what properties were sent in the req.body and build out the query accordingly.
N.B: You must have some validation to check the request body to ensure no unwanted properties are sent. You can use a package like Joi
const getContact = await contact.findOne({ id: req.params.id });
let query = { $addToSet: {} };
for (let key in req.body) {
if (getContact[key] && getContact[key] !== req.body[key])// if the field we have in req.body exists, we're gonna update it
query.$addToSet[key] = req.body[key];
}
const contact = await Customer.findOneAndUpdate(
{ pid: req.params.id },
query,
{new: true}
);
Upvotes: 3
Reputation: 388
With mongoose, you can use $push to push object to array. The query will be like:
(saving an address and an email, querying on pid)
db.getCollection("contactSchema").update({"pid":1}, {$push: {email: emailToPush,
address:addressToPush}})
{"pid":1} is the pid of the object you want to update;
{$push: {email: emailToPush, address:addressToPush}} is the object you want to push on each array
Then you have to filter the body of the request with a middleware or something like that. I usually use a middleware to check if the request is correct, like:
EDIT:
const buildQuery = (requestBody) => {
let query = {$push: {}};
Object.keys(requestBody).map(key => {
query.$push[key] = requestBody[key];
});
}
This will build your query object (the second parameter of the update function).
Upvotes: 3