This is the 29th day of my participation in the August More Text Challenge

Mongoose’s save() method is one way to save document changes to a database. There are several methods to update a document in Mongoose, such as Update and updateOne. But Save () is the most full-featured method. Save () should be used to update the document unless there is a good reason not to.

usesave()operate

Save () is one method on Mongoose Documents. The save() method is asynchronous, so it returns a Promise that can be await.

When you create an instance of the Mongoose model with new, calling save() causes Mongoose to insert a new document.

const Person = mongoose.model('Person', Schema({
  name: String.rank: Number
}))
​
const doc = new Person({
  name: 'O.O'.age: 18
})
// Insert a new document with name = O.O, age = 18
await doc.save()
​
const person = await Person.findOne()
console.log(person.name) // O.O
Copy the code

Save () updates the existing document if it is loaded from the database and modified.

const person = await Person.findOne()
person.name // O.O// Mongoose tracks changes to the document. Mongoose tracks the age property you set and persists the changes to the database.
person.age = 18
await person.save()
​
// Load the document from the database and view the changes
const docs = await Person.find()
​
console.log(docs.length) / / 1
console.log(docs[0].age) / / 18
Copy the code

Mongoose’s change trace sends minimal updates to MongoDB based on the changes you make to the document. You can set Mongoose debug mode to see the operations Mongoose sends to MongoDB.

mongoose.set('debug'.true)
​
person.age = 18
// Mongoose: people.updateOne({ _id: ObjectId("..." ) }, { '$set': { age: 18 } })
await person.save()
Copy the code

validation

Mongoose verifies the modified path before saving it. If you set the field to an invalid value, Mongoose will throw an error when trying to save() the document.

const Person = mongoose.model('Person', Schema({
  name: String.age: Number
}))
​
const doc = await Person.create({ name: 'Will Riker'.age: 18 })
​
// It is ok to set name to invalid value...
doc.age = 'lotto'// But the document fails when you try to save()
const err = await doc.save().catch(err= > err)
err // The cast of lotto at path age failed// However, if age is set to a valid value, save() succeeds.
doc.age = 20
await doc.save()
Copy the code

The middleware

The Mongoose middleware allows you to tell Mongoose to execute a method every time you call save(). For example, calling pre(‘save’) tells Mongoose to execute a method before executing save().

const schema = Schema({ name: String.age: Number })
schema.pre('save'.function() {
  // In save middleware, this is the document being saved.
  console.log('Save'.this.name)
})
const Person = mongoose.model('Person', schema)
​
const doc = new Person({ name: 'O.O'.age: 18 })
​
// Save O.O
await doc.save()
Copy the code

Similarly, Post (‘save’) tells Mongoose to execute a method after calling save(). For example, you can combine pre(‘save’) and POST (‘save’) to print the time taken for save().

const schema = Schema({ name: String.age: Number })
schema.pre('save'.function() {
  this.$locals.start = Date.now()
})
schema.post('save'.function() {
  console.log('Save time as'.Date.now() - this.$locals.start, ' ms')})const Person = mongoose.model('Person', schema)
​
const doc = new Person({ name: 'O.O'.age: 18 })
​
// The storage time is 12 ms
await doc.save()
Copy the code

The Save () middleware is recursive, so calling save() on the parent document also triggers the save() middleware for the child document.

const friendSchema = Schema({ name: String.age: Number.hobby: String })
friendSchema.pre('save'.function() {
  console.log('Save'.this.hobby)
})
const schema = Schema({
  name: String.age: Number.friend: friendSchema
})
const Person = mongoose.model('Person', schema)
​
const doc = new Person({
  name: 'O.O'.age: 18.friend: {
    name: 'D.O'.age: 20.hobby: 'sing'}})// Save sing
await doc.save()
​
doc.friend.hobby = 'dance'
// Save dance
await doc.save()
Copy the code