Reputation: 4805
I have an object like follows;
var exObj = { 'title' : 'name1'};
some of them have a data property of objects (not an array as I want to reference by name) and look like
exObj = {
title : 'name2',
data : {
prop1 : 'prop1',
prop2 : 'prop2'
}
}
Now I want to add another property to data, sometimes the data property will exist, and sometimes not, but I want to append a property (addedProp) and save it so I will end up with this;
exObj = {
title : 'name2',
data : {
prop1 : 'prop1',
prop2 : 'prop2',
addedProp : 'value'
}
}
When using findOneAndUpdate I can only seem to pass in a whole object which is then appended; something like this is what I currently do.
var data = {};
data.addedProp = value;
Collection.findOneAndUpdate({
title: 'name2'
}, {
data
}, {
upsert: true
})
.exec(function(err) {
if (err) {
console.log(err);
} else {
console.log('Updated');
}
});
But obviously this overides the data object that exists; what is the correct way to do a findOneAndUpdate and make more meaningful changes to the object? I tried casting to toObject() but then I don't have a proper mongoose object to do a .save() on.
To add further clarification; which this worked for simple properties (and worked well) which I know are set; there are some values I wish to add which I need to check if they have a value for the property before adding the property.
So something like this;
Collection.findOneAndUpdate({
field: val
}, {
if (tObj.title) {
title = tObj.title;
}
if (tObj.date) {
release_date = tObj.date;
}
if (tObj.name) {
name = tObj.name;
}
}, { upsert: true
})
.exec(function(err) {
if (err) {
//handler
} else {
//handler
}
});
Upvotes: 3
Views: 2723
Reputation: 312035
You need to use dot notation to target specific fields within an embedded object, building up your update object based on the supplied fields:
var update = {};
if (tObj.title) {
update.title = tObj.title;
}
if (tObj.data) {
if (tObj.data.prop1) {
update['data.prop1'] = tObj.data.prop1;
}
if (tObj.data.prop2) {
update['data.prop2'] = tObj.data.prop2;
}
if (tObj.data.addedProp) {
update['data.addedProp'] = tObj.data.addedProp;
}
}
Collection.findOneAndUpdate({
title: 'name2'
}, {
$set: update
}, {
upsert: true
})
.exec(function(err) {
Upvotes: 0
Reputation: 3543
Your question first seem daunting, but solution is quite simple, you don't need to use $ or upsert, because you are not using any array , so don't need of positional operator or upsert. You can use below code.
Collection.findOneAndUpdate({
title: 'name2'
},{
$set:{"data.prop3":"new prop3"}
})
.exec(function(err) {
if (err) {
console.log(err);
} else {
console.log('Updated');
}
});
It will add prop3 if not exists, or if it exists it will update it. I have checked the code on my local db with update and findOneAndUpdate
Upvotes: 3