Skip to content

Commit

Permalink
fix(document): avoid massive perf degradation when saving new doc wit…
Browse files Browse the repository at this point in the history
…h 10 level deep subdocs

Fix #14897
  • Loading branch information
vkarpov15 committed Sep 24, 2024
1 parent f9ca745 commit 328ddaa
Show file tree
Hide file tree
Showing 2 changed files with 24 additions and 1 deletion.
4 changes: 3 additions & 1 deletion lib/document.js
Original file line number Diff line number Diff line change
Expand Up @@ -2724,7 +2724,9 @@ function _getPathsToValidate(doc, pathsToValidate, pathsToSkip) {
}

if (doc.$isModified(fullPathToSubdoc, null, modifiedPaths) &&
!doc.isDirectModified(fullPathToSubdoc) &&
// Avoid using isDirectModified() here because that does additional checks on whether the parent path
// is direct modified, which can cause performance issues re: gh-14897
!doc.$__.activePaths.getStatePaths('modify').hasOwnProperty(fullPathToSubdoc) &&
!doc.$isDefault(fullPathToSubdoc)) {
paths.add(fullPathToSubdoc);

Expand Down
21 changes: 21 additions & 0 deletions test/document.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13905,6 +13905,27 @@ describe('document', function() {
const objectWithGetters = result.toObject({ getters: true, virtuals: false });
assert.strictEqual(objectWithGetters.level1.level2.level3.property, 'TESTVALUE');
});

it('handles inserting and saving large document with 10-level deep subdocs (gh-14897)', async function() {
const levels = 10;

let schema = new Schema({ test: { type: String, required: true } });
let doc = { test: 'gh-14897' };
for (let i = 0; i < levels; ++i) {
schema = new Schema({ level: Number, subdocs: [schema] });
doc = { level: (levels - i), subdocs: [{ ...doc }, { ...doc }] };
}

const Test = db.model('Test', schema);
const savedDoc = await Test.create(doc);

let cur = savedDoc;
for (let i = 0; i < levels - 1; ++i) {
cur = cur.subdocs[0];
}
cur.subdocs[0] = { test: 'updated' };
await savedDoc.save();
});
});

describe('Check if instance function that is supplied in schema option is available', function() {
Expand Down

0 comments on commit 328ddaa

Please # to comment.