Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Mongoose validates all array items when one entry is updated #9963

Closed
lvkins opened this issue Feb 22, 2021 · 1 comment
Closed

Mongoose validates all array items when one entry is updated #9963

lvkins opened this issue Feb 22, 2021 · 1 comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@lvkins
Copy link

lvkins commented Feb 22, 2021

Do you want to request a feature or report a bug?

Possibly a bug

What is the current behavior?

Document.set causes entire schema array validation.

If the current behavior is a bug, please provide the steps to reproduce.

When using the following schema:

const SectionSchema = new Schema({
	title: {
		type: String,
		required: true,
		maxlength: 24
	},
	state: {
		type: String,
		validate: function(v) {
			console.log(`@section '${this.title}' state is validating`)
			return true;
		}
	}
}, {_id: false});

const RootSchema = new Schema({
    name: {
		type: String,
		required: true
	},
    sections: [SectionSchema]
});

Updating a SectionSchema state by a dot notation path through the set and save triggers all RootSchema sections array items validate methods:

// Entries in the Root schema:
// { name: "Test1, sections: [{ title: "foo", state: ""}, { title: "bar", state: ""}, , { title: "boo", state: ""}] }

const doc = Root.findOne({name: "Test1"})
// Update first section state
doc.set("sections.0.state", "hello world", String);
// Commit modified-only changes
await doc.save({validateModifiedOnly: true});

// Console output (should've validate only updated field in this case)
// @section 'foo' state is validating
// @section 'bar' state is validating
// @section 'boo' state is validating

This is interesting, because updateOne behavior is slightly different and it just works fine while updating the same path:

const doc = Root.findOne({name: "Test1"})

// Update directly
await doc.updateOne({
    $set: { "sections.0.state": "john doe" }
}, { runValidators: true });

// Console output:
// @section 'foo' state is validating

I cannot make use of the updateOne because I need to utilize the save middleware.

What is the expected behavior?

When using Document.prototype.set to explicitly update a value, I believe that mongoose shouldn't wastefully validate unmodified array items.

What are the versions of Node.js, Mongoose and MongoDB you are using? Note that "latest" is not a version.

  • mongodb: 3.6.4
  • mongoose: 5.11.8
  • nodejs: 14.10.0
@IslandRhythms
Copy link
Collaborator

IslandRhythms commented Feb 23, 2021

const mongoose = require('mongoose');

const SectionSchema = new mongoose.Schema({
	title: {
		type: String,
		required: true,
		maxlength: 24
	},
	state: {
		type: String,
		validate: function(v) {
			console.log(`@section '${this.title}' state is validating`)
			return true;
		}
	}
}, {_id: false});

const RootSchema = new mongoose.Schema({
    name: {
		type: String,
		required: true
	},
    sections: [SectionSchema]
});
const Root = mongoose.model('Root', RootSchema);

(async function() {
  await mongoose.connect('mongodb://localhost:27017/test', {
    useNewUrlParser: true,
    useUnifiedTopology: true
  });

  await Root.create({
    name: 'Test1',
    sections: [{title: 'foo', state: ""}, {title: 'bar', state: ""}, ,{title: "boo", state:""}],
  });
  console.log(user.name);
  const doc = await Root.findOne({name: "Test1"});
  //doc.set("sections.0.state", "hello world", String);
  //await doc.save({validateModifiedOnly: true});

  await doc.updateOne({
    $set: {"sections.0.state": "john doe"}}, {runValidators: true})
})();

@IslandRhythms IslandRhythms added needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed needs repro script Maybe a bug, but no repro script. The issue reporter should create a script that demos the issue can't reproduce Mongoose devs have been unable to reproduce this issue. Close after 14 days of inactivity. aware labels Feb 24, 2021
@vkarpov15 vkarpov15 added this to the 5.11.19 milestone Mar 1, 2021
@vkarpov15 vkarpov15 removed the has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue label Mar 2, 2021
vkarpov15 added a commit that referenced this issue Mar 2, 2021
This was referenced Mar 12, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Projects
None yet
Development

No branches or pull requests

3 participants