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

Can not update sub schema to empty object #14420

Closed
2 tasks done
emiljanitzek opened this issue Mar 7, 2024 · 4 comments · Fixed by #14437
Closed
2 tasks done

Can not update sub schema to empty object #14420

emiljanitzek opened this issue Mar 7, 2024 · 4 comments · Fixed by #14437
Labels
confirmed-bug We've confirmed this is a bug in Mongoose and will fix it.
Milestone

Comments

@emiljanitzek
Copy link
Contributor

Prerequisites

  • I have written a descriptive issue title
  • I have searched existing issues to ensure the bug has not already been reported

Mongoose version

8.2.1

Node.js version

20.11.1

MongoDB server version

4.4

Typescript version (if applicable)

No response

Description

We ran in to an issue while migrating from mongoose 6 when trying to set the path of a sub scehma to an empty object (clearing all data). The change is reflected in the local document and the modifiedPaths() says that the attribute has been changed. But the change is not saved in the database.

Steps to Reproduce

await mongoose.connect('mongodb://localhost:27017/mongoose_test');
console.log(mongoose.version);

const SubSchema = new mongoose.Schema({
	name: {type: String}
}, { _id: false });

const MainSchema = new mongoose.Schema({
	sub: { 
			type: SubSchema,
		}
});

const MainModel = mongoose.model('Main', MainSchema);

const doc = new MainModel({ sub: { name: 'Hello World' } });
console.log('init', doc.sub); // { name: 'Hello World' }
await doc.save();

doc.set({ sub: {} });
await doc.save();
console.log('save', doc.sub); // {} empty as expected

const savedDoc = await MainModel.findById(doc.id).orFail();
console.log('findById', savedDoc.sub); // { name: 'Hello World' } still has old value

Expected Behavior

The change in the local document to be updated in the database.

@IslandRhythms IslandRhythms added has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue confirmed-bug We've confirmed this is a bug in Mongoose and will fix it. and removed has repro script There is a repro script, the Mongoose devs need to confirm that it reproduces the issue labels Mar 7, 2024
@IslandRhythms
Copy link
Collaborator

This may be expected behavior but labeling as confirmed bug just in case. I believe if you want to remove data from a document you have to set it to undefined if I remember correctly.

const mongoose = require('mongoose');

  
const SubSchema = new mongoose.Schema({
  name: {type: String}
}, { _id: false });

const MainSchema = new mongoose.Schema({
  sub: { 
      type: SubSchema,
    }
});

const MainModel = mongoose.model('Main', MainSchema);

run().catch(e => console.log(e))

async function run() {
  await mongoose.connect('mongodb://localhost:27017/mongoose_test');
  await mongoose.connection.dropDatabase();
  console.log(mongoose.version);

  
  const doc = new MainModel({ sub: { name: 'Hello World' } });
  console.log('init', doc.sub); // { name: 'Hello World' }
  await doc.save();
  
  doc.set({ sub: {} });
  await doc.save();
  console.log('save an expected empy object', doc.sub); // {} empty as expected
  
  const savedDoc = await MainModel.findById(doc.id).orFail();
  console.log('findById', savedDoc.sub); // { name: 'Hello World' } still has old value
}

@donoftime2018
Copy link

Why did you put _id:false in the schema if you wanted to find a document via findById? Maybe try removing the _id:false from the schema and see what happens?

@emiljanitzek
Copy link
Contributor Author

This may be expected behavior but labeling as confirmed bug just in case. I believe if you want to remove data from a document you have to set it to undefined if I remember correctly.

Thank you for looking in to this @IslandRhythms. When did this behaviour change? Couldn't find any breaking changes in the change log. This worked fine in 6.x. I also find it confusing that the local document has a different state (correct state in my mind) and the change tracking stays that there is a change? But this change is not saved to the database.

You are correct that setting it to undefined works. But it seems strange that I can assign the value {}and it will set it to an empty object. But not clearing the data with an empty object. It also adds a lot of extra logic in my code to check if the object is empty and then set it to undefined every time I do an update.

Why did you put _id:false in the schema if you wanted to find a document via findById? Maybe try removing the _id:false from the schema and see what happens?

The _id: false is just on my sub document that is an embedded document, can't see how this would affect this bug (could have removed it in my example if it was confusing)

@donoftime2018
Copy link

donoftime2018 commented Mar 8, 2024

I recommend you take a look at this issue.

@vkarpov15 vkarpov15 added this to the 8.2.2 milestone Mar 13, 2024
vkarpov15 added a commit that referenced this issue Mar 14, 2024
vkarpov15 added a commit that referenced this issue Mar 15, 2024
fix(model): improve update minimizing to only minimize top-level properties in the update
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
4 participants