Calling findOneAndUpdate
with $setOnInsert
and setDefaultsOnInsert: true, upsert: true
on a nested subdocument with a default value for a field results in the error:
Updating the path 'nested.subdocument.default_field' would create a conflict at 'nested.subdocument'
MongoDB: 3.6.5
Mongoose v.5.2.1
Node v.8.11.3
const mongoose = require('mongoose');
const BugSchema = new mongoose.Schema({
nested: {
test: String,
default_field: {
type: Number,
default: 100,
},
subdocument: {
test: String,
default_field: {
type: Number,
default: 100,
},
},
},
});
const BugModel = mongoose.model('BugSchema', BugSchema);
mongoose
.connect('mongodb://localhost:27017')
.then(() => {
const failingUpdate = {
'nested.subdocument': {
test: 'Value',
},
};
const passingUpdate = {
'nested.subdocument': {
test: 'Value',
default_field: 100, // Note: Must set default_field value to prevent error.
}
};
const passingUpdate2 = {
'nested': {
test: 'Value', // Note: No default_field value set.
},
};
return bugModeQuery(failingUpdate)
.then(() => bugModeQuery(passingUpdate))
.then(() => bugModeQuery(passingUpdate2))
.then(() => {
mongoose.connection.close();
process.exit();
})
})
.catch(err => {
console.error(err);
mongoose.connection.close();
process.exit();
});
function bugModeQuery(update) {
return BugModel.findOneAndUpdate(
{},
{$setOnInsert: update},
{
setDefaultsOnInsert: true,
upsert: true,
}
)
.then(res => {
console.log('Success');
console.log(res);
return;
})
.catch(err => {
console.error('ERROR');
console.error(err);
return Promise.resolve();
})
}
@redwood-egarcea the dot notation in the update doc seems to make mongodb unhappy, if you change your failingUpdate to:
const failingUpdate = {
nested: {
subdocument: {
test: 'Value',
}
},
};
The mongoose debug logs show that using dot notation in the update doc causes mongoose to send a different update doc that mongodb bugs out on:
Mongoose: bugschemas.findAndModify({}, [], { '$setOnInsert': { 'nested.subdocument': { test: 'Value' }, __v: 0, 'nested.default_field': 100, 'nested.subdocument.default_field': 100, _id: ObjectId("5b3d3b94df1e2a4cb1da3604") } }, { setDefaultsOnInsert: true, upsert: true, new: false, remove: false, fields: {} })
Mongoose: bugschemas.findAndModify({}, [], { '$setOnInsert': { nested: { subdocument: { test: 'Value' } }, __v: 0, _id: ObjectId("5b3d3bcdaf22214cf1f77637") } }, { setDefaultsOnInsert: true, upsert: true, new: false, remove: false, fields: {} })
@vkarpov15 using dot notation in the update doc of a query isn't something I've seen before. Is this supported?
I grok'd the tests regarding updates and I do see some usage of dot notation in the update doc but it seems to always be associated with arrays. Hopefully I get points for trying :)
@lineus yep that is supported. This is definitely a bug, will fix asap :+1:
Most helpful comment
@lineus yep that is supported. This is definitely a bug, will fix asap :+1: