I have the next document, and I want to update the addresses with id of 21, change the alias to 'Family'. I run User.update({ _id: 2, 'addresses._id': 21 }, { 'addresses.$': newAddress });
Which works fine, with an annoying side effect, is that Mongo generates a new id for the subdocument. Is there any way to update a subdocument without getting a new id?
'user': {
'_id': 2,
'addresses': [
{
'_id': '20',
'alias': 'Work',
'postal_code': 1235
},
{
'_id': '21',
'alias': 'Home',
'postal_code': 1235
}
]
}
I already solved this using
User.update(
{ _id: req.user._id, 'addresses._id': addressId },
{ $set: {
'addresses.$.alias': newAddress.alias,
'addresses.$.address': newAddress.address,
'addresses.$.areaId': newAddress.areaId,
'addresses.$.cityId': newAddress.cityId,
'addresses.$.postal_code': newAddress.postal_code
} }
);
This doesn't change the id of the subdocument, but I don't like this solution for obvious reasons.
Adding to JasonCust's answer, the correct approach is to inject the old id into the new address to keep the id unchanged and avoid having to enter each individual key.
Below is an example:
const userSchema = new Schema({
addresses: [{ country: String }]
});
const User = mongoose.model('User', userSchema);
const user = await User.create({
addresses: [
{ country: 'Egypt' }
]
});
const oldAddressId = user.addresses[0]._id;
//
const newAddress = {
_id: oldAddressId,
country: 'Japan'
};
await User.updateOne({ 'addresses._id': oldAddressId }, { 'addresses.$': newAddress });
const userAfterUpdate = await User.findOne({ _id: user._id });
assert.equal(userAfterUpdate.addresses[0].country, 'Japan');
assert.equal(userAfterUpdate.addresses[0]._id.toString(), oldAddressId.toString());
The short answer is: no. In essence the update object { 'addresses.$': newAddress }
is a command to replace the entire object at the matched pointer location with the newAddress
object. That said, if the newAddress
object includes the _id
value then it should be stored as the value.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With