Mongoose 的 save() 方法

Mongoose 的 save() 方法是将文档更改保存到数据库的一种方法。在 Mongoose 中更新文档有几种方法,如:updateupdateOne。但 save() 是功能最齐全的方法。除非有充分理由不更新文档,否则应使用 save() 更新文档。

使用 save() 进行操作

save()Mongoose documents 上的一个方法。save() 方法是异步的,因此它返回一个可以 await 执行的 Promise。

当您使用 new 创建 Mongoose 模型的实例时,调用 save() 会使 Mongoose 插入一个新文档。

const Person = mongoose.model('Person', Schema({
  name: String,
  rank: Number
}))

const doc = new Person({
  name: 'O.O',
  age: 18
})
// 插入一个 name = O.O, age = 18 的新文档
await doc.save()

const person = await Person.findOne()
console.log(person.name) // O.O

如果从数据库加载现有文档并对其进行修改,则 save() 会更新现有文档。

const person = await Person.findOne()
person.name // O.O

// Mongoose 跟踪文档的更改。Mongoose 跟踪您设置的 age 属性,并将更改持久化到数据库中。
person.age = 18
await person.save()

// 从数据库加载文档并查看更改
const docs = await Person.find()

console.log(docs.length) // 1
console.log(docs[0].age) // 18

Mongoose 的更改跟踪根据您对文档所做的更改向 MongoDB 发送最小更新。您可以设置 Mongoose 的调试模式,以查看 Mongoose 发送给 MongoDB 的操作。

mongoose.set('debug', true)

person.age = 18
// Mongoose: people.updateOne({ _id: ObjectId("...") }, { '$set': { age: 18 } })
await person.save()

验证

Mongoose 在保存之前验证修改后的路径。如果将字段设置为无效值,Mongoose 将在尝试 save() 该文档时抛出错误。

const Person = mongoose.model('Person', Schema({
  name: String,
  age: Number
}))

const doc = await Person.create({ name: 'Will Riker', age: 18 })

// 将 name 设置为无效值是可以的。。。
doc.age = 'lotto'

// 但尝试 save() 时,文档会出错
const err = await doc.save().catch(err => err)
err // 路径 age 处的值 lotto 的强制转换为数字失败

// 但是,如果将 age 设置为有效值,则 save() 将成功。
doc.age = 20
await doc.save()

中间件

Mongoose 中间件允许您在每次调用 save() 时告诉 Mongoose 执行一个方法。例如,调用 pre('save') 告诉 Mongoose在执行 save() 之前先执行一个方法。

const schema = Schema({ name: String, age: Number })
schema.pre('save', function() {
  // 在 save 中间件中,this 是正在保存的文档。
  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()

类似地,post('save') 告诉 Mongoose 在调用 save() 后执行一个方法。例如,您可以将 pre('save')post('save') 组合起来打印 save() 所用的时间。

const schema = Schema({ name: String, age: Number })
schema.pre('save', function() {
  this.$locals.start = Date.now()
})
schema.post('save', function() {
  console.log('保存时间为 ', Date.now() - this.$locals.start, ' ms')
})
const Person = mongoose.model('Person', schema)

const doc = new Person({ name: 'O.O', age: 18 })

// 保存时间为 12 ms
await doc.save()

save() 中间件是递归的,因此对父文档调用 save() 也会触发子文档的 save() 中间件。

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()
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值