admin管理员组文章数量:1134556
To modify a field in an existing entry in mongoose, what is the difference between using
model = new Model([...])
model.field = 'new value';
model.save();
and this
Model.update({[...]}, {$set: {field: 'new value'});
The reason I'm asking this question is because of someone's suggestion to an issue I posted yesterday: NodeJS and Mongo - Unexpected behaviors when multiple users send requests simultaneously. The person suggested to use update instead of save, and I'm not yet completely sure why it would make a difference.
Thanks!
To modify a field in an existing entry in mongoose, what is the difference between using
model = new Model([...])
model.field = 'new value';
model.save();
and this
Model.update({[...]}, {$set: {field: 'new value'});
The reason I'm asking this question is because of someone's suggestion to an issue I posted yesterday: NodeJS and Mongo - Unexpected behaviors when multiple users send requests simultaneously. The person suggested to use update instead of save, and I'm not yet completely sure why it would make a difference.
Thanks!
Share Improve this question edited Jun 26, 2017 at 10:50 Neil Lunn 151k36 gold badges354 silver badges324 bronze badges asked Mar 9, 2014 at 5:25 Edward SunEdward Sun 1,6214 gold badges16 silver badges27 bronze badges 2 |4 Answers
Reset to default 172Two concepts first. Your application is the Client, Mongodb is the Server.
The main difference is that with .save()
you already have an object in your client side code or had to retrieve the data from the server before you are writing it back, and you are writing back the whole thing.
On the other hand .update()
does not require the data to be loaded to the client from the server. All of the interaction happens server side without retrieving to the client.So .update()
can be very efficient in this way when you are adding content to existing documents.
In addition, there is the multi
parameter to .update()
that allows the actions to be performed on more than one document that matches the query condition.
There are some things in convenience methods that you lose when using .update()
as a call, but the benefits for certain operations is the "trade-off" you have to bear. For more information on this, and the options available, see the documentation.
In short .save()
is a client side interface, .update()
is server side.
Some differences:
- As noted elsewhere,
update
is more efficient thanfind
followed bysave
because it avoids loading the whole document. - A Mongoose
update
translates into a MongoDBupdate
but a Mongoosesave
is converted into either a MongoDBinsert
(for a new document) or anupdate
. - It's important to note that on
save
, Mongoose internally diffs the document and only sends the fields that have actually changed. This is good for atomicity. - By default validation is not run on
update
but it can be enabled. - The middleware API (
pre
andpost
hooks) is different.
There is a useful feature on Mongoose called Middleware. There are 'pre' and 'post' middleware. The middlewares get executed when you do a 'save', but not during 'update'. For example, if you want to hash a password in the User schema everytime the password is modified, you can use the pre to do it as follows. Another useful example is to set the lastModified for each document. The documentation can be found at http://mongoosejs.com/docs/middleware.html
UserSchema.pre('save', function(next) {
var user = this;
// only hash the password if it has been modified (or is new)
if (!user.isModified('password')) {
console.log('password not modified');
return next();
}
console.log('password modified');
// generate a salt
bcrypt.genSalt(10, function(err, salt) {
if (err) {
return next(err);
}
// hash the password along with our new salt
bcrypt.hash(user.password, salt, function(err, hash) {
if (err) {
return next(err);
}
// override the cleartext password with the hashed one
user.password = hash;
next();
});
});
});
One detail that should not be taken lightly: concurrency
As previously mentioned, when doing a doc.save()
, you have to load a document into memory first, then modify it, and finally, doc.save()
the changes to the MongoDB server.
The issue arises when a document is edited that way concurrently:
- Person A loads the document (v1)
- Person B loads the document (v1)
- Person B saves changes to the document (it is now v2)
- Person A saves changes to an outdated (v1) document
- Person A will see Mongoose throw a VersionError because the document has changed since last loaded from the collection
Concurrency is not an issue when doing atomic operations like Model.updateOne()
, because the operation is done entirely in the MongoDB server, which performs a certain degree of concurrency control.
Therefore, beware!
本文标签: javascriptMongoose difference between save() and using update()Stack Overflow
版权声明:本文标题:javascript - Mongoose difference between .save() and using update() - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1736858771a1955823.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
model = new Model(...)
isn't going to update anything, because it creates a new document. I think the question would be better without that confusion. – joeytwiddle Commented Apr 20, 2016 at 6:10