Automattic / Automattic/mongoose
(4.6.2 -> 4.6.3 regression) Calling .set on a subfield of a deselected subdoc wipes out other fields on the subdoc
- Dominant language
- JavaScript
- Stars
- 27.5k
- Forks
- 4k
- Avg merge
- 2d 7h
- Merged PRs (30d)
- 35
Description
Suppose I have a schema defining a single embedded subdocument. I don't select this subdocument when I fetch the parent document, but I set a field on it anyway using .set.
In 4.6.2, this works as expected: the field I set changes, and the rest of the subdocument remains unchanged.
In 4.6.3, this wipes out the rest of the subdocument's fields, and gives it a new ID.
This feels like a bug, though it may be intended behavior.
``` javascript
const mongoose = require('mongoose');
const Promise = require('bluebird');
mongoose.Promise = Promise;
const connection = mongoose.connect('mongodb://localhost/minimal', {});
mongoose.set('debug', true);
const ballSchema = mongoose.Schema({
kind: String,
mass: Number
});
const sportSchema = mongoose.Schema({
ball: ballSchema
});
const Sport = mongoose.model('Sport', sportSchema);
new Sport({ball: {kind: 'birdie', mass: 4.75 }}).save()
.then((sport) => Sport.findById(sport._id).select('-ball'))
.then((sport) => {
sport.set('ball.kind', 'shuttlecock');
// On 4.6.2, this save issues this update:
// sports.update({ _id: ObjectId(...) },
// { '$set': { 'ball.kind': 'shuttlecock' } })
// On 4.6.3, it issues this update:
// sports.update({ _id: ObjectId("...") },
// { '$set': { ball: { kind: 'shuttlecock', _id: ObjectId("...") } } })
return sport.save();
})
.then((sport) => Sport.findById(sport._id).select('ball'))
.then((sport) => {
// On 4.6.2, sport.ball.mass === 4.7.5
// On 4.6.3, sport.ball.mass is undefined
console.log('sport.ball.mass', sport.ball.mass);
});
```
Contributor guide
Research direction
Start by running the supplied JavaScript reproduction against Mongoose 4.6.3 and compare the generated update with the 4.6.2 behavior. Trace the .set('ball.kind', ...) and subsequent save() path for a deselected subdocument. Done means changing kind preserves mass and the existing subdocument ID instead of replacing the whole subdocument.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- javascript, mongodb
- Domain
- backend, database
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 32/100