-
-
Notifications
You must be signed in to change notification settings - Fork 3.9k
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
first remove, then save, why there is no data? #8371
Comments
Because under the hood, Therefore, the code you have attempts to save a document that is removed, but since you haven't made any modifications, mongoose doesn't bother sending a command to the database to update your document, and fails silently, which in my opinion can be confusing, even if it's not clear why the logic would try to remove a document, and then try to save it. const mongoose = require('mongoose');
mongoose.connect('mongodb://localhost:27017/test', { useUnifiedTopology: true, useNewUrlParser: true, useFindAndModify: true });
const Person = mongoose.model('gh8371', { name: String });
async function run () {
await Person.deleteMany();
await Person.create({ name: 'Sam' });
const removedPerson = await Person.findOneAndRemove({ name: 'Sam' });
removedPerson.name = 'Hafez'; // removing this line would make the code fail silently
await removedPerson.save();
console.log('Done.');
}
run().catch(console.error); @vkarpov15 Some options to consider: Add a key in a document that is retrieved via findOneAnd(Remove/Delete) A) Call Model.create(document.toObject()); to re-create that document. B) Throw an error on calling I am inclining to option B. The code snippet below will probably achieve what you want, even though I recommend rethinking the logic of the application in the first place. const mongoose = require('mongoose');
mongoose.connect('mongodb://127.0.0.1:27017/test', { family: 4, useCreateIndex: true, useFindAndModify: false, useNewUrlParser: true, useUnifiedTopology: true, poolSize: 10 });
const Person = mongoose.model('gh8371', { name: String });
async function run () {
await Person.deleteMany();
await Person.create({ name: 'Sam' });
const removedPerson = await Person.findOneAndRemove({ name: 'Sam' });
removedPerson.name = 'Hafez';
await Person.create(removedPerson.toObject());
console.log('Done.');
}
run().catch(console.error); |
I tried to run the code let acl = await Acl.findOneAndRemove({name: "nodejs"});
acl.isNew = true;
let newAcl = await acl.save();
console.log(newAcl); I think: fails silently is unreasonable.... the logic of the code is to save the data (ignore the contradiction of the code logic), and there is no error message after execution. so i think that the data is saved successfully. but the reality is that there is no data.... this is understandable to senior users.. but it's confusing for junior users. |
While it's not clear to me why you would want to remove a document, then save it right after. I agree that you should be informed that the document is not saved in some way. Waiting for @vkarpov15 's take on this issue. |
@vkarpov15 I find this an interesting challenge. Would be more than happy to help implement a fix if you let me know what you have on mind regarding this issue. |
@AbdelrahmanHafez at the very least, setting I'm a bit less confident that |
@AbdelrahmanHafez @vkarpov15 what can I do for mongoose? I'm willing to contribute to make mongoose better. |
I just added a test verifying the behavior for setting const assert = require('assert');
const mongoose = require('./index');
const { Schema } = mongoose;
const userSchema = new Schema({ name: String });
const User = mongoose.model('User', userSchema);
mongoose.connect('mongodb://127.0.0.1:27017/test', { useNewUrlParser: true, useUnifiedTopology: true });
async function run () {
const createdUser = await User.create({ name: 'Hafez' });
const removedUser = await User.findOneAndRemove({ _id: createdUser._id });
removedUser.isNew = true;
await removedUser.save();
const foundUser = await User.findOne({ _id: removedUser._id });
assert.ok(foundUser);
}
run().catch(console.error); @LeonYanghaha this is what you're trying to achieve in #8371 (comment), right? If yes, and you're still having a problem with that, please try to provide a reproduction script. @vkarpov15 I came up with an approach that I think will be cleaner than setting isNew on The current behavior is: if (doc.isNew) {
//insert
} else {
const changes = this.getChanges();
if (changes) {
// update with changes
}
} which results in failing silently when no changes are present, this could be fixed by: if (doc.isNew) {
//insert
} else {
const changes = this.getChanges();
if (changes) {
// update with changes
} else {
//check doc existence on db, if it's not found, throw an error, otherwise go on.
}
} |
please ignore the contradiction of code logic. after the following code is executed, there is no data in mongodb. who can tell me why? according to my understanding, execute
document.save()
can insert data, but now there is no data. it's strange.nodejs:10.16.3
mongoose: 5.6.9
The text was updated successfully, but these errors were encountered: