Mongoose 更新文档

本文已整理到 Github,地址 👉 blog

如果我的内容帮助到了您,欢迎点个 Star 🎉🎉🎉 鼓励鼓励 :) ~~

我希望我的内容可以帮助你。现在我专注于前端领域,但我也将分享我在有限的时间内看到和感受到的东西。


Mongoose 有 4 种不同的方式来更新文档。

  • Document.save()
  • Model.updateOne()updateMany()
  • Document.updateOne()
  • Model.findOneAndUpdate()

使用 save()

下面是使用 save() 更新标题的示例。

const schema = new mongoose.Schema({ name: String, title: String })
const ArticleModel = mongoose.model('Article', schema)

const doc = await ArticleModel.create({
  name: 'lio-zero',
  title: 'Mongoose 更新文档'
})

// 通过设置属性并调用 save() 更新文档
doc.title = '使用 save() 方法更新文档'
await doc.save()

这个简单的例子有几个细微差别。首先,save()是文档上的一个方法,这意味着您必须有一个要保存的文档。您需要使用 create() 或使用 find() 来获取文件。

其次,Mongoose 文档具有更改跟踪功能。当您调用时 doc.save(),Mongoose 知道您设置 title 并将您的 save() 调用转换为 updateOne({ $set: { title } })。尝试在调试模式下运行 Mongoose 以查看 Mongoose 执行的查询。

使用 Model.updateOne() 和 Model.updateMany()

使用 Model.updateOne()Model.updateMany(),您可以更新文档,而无需先从数据库加载它。在下面的示例中,当 updateOne() 被调用时,name = 'lio-zero' 的文档不在 Node.js 进程的内存中。

// 使用 updateOne() 更新文档
await ArticleModel.updateOne(
  { name: 'lio-zero' },
  {
    title: '使用 updateOne() 方法更新文档'
  }
)

// 加载文档以查看更新的值
const doc = await ArticleModel.findOne()
doc.title // '使用 updateOne() 方法更新文档'

如果你想在 Mongoose 中用一个命令更新多个文档,你应该使用 updateMany() 方法。

await ArticleModel.create({ name: 'lio' })
await ArticleModel.create({ name: 'lion' })
await ArticleModel.create({ name: 'lio-zero' })

// 在所有文档上设置 title 属性
await ArticleModel.updateMany({}, { title: '使用 updateMany() 方法更新文档' })

// 设置 name 以 o 结尾的文档的 title 属性
await ArticleModel.updateMany(
  { name: /o$/ },
  { $set: { title: '使用 updateMany() 方法更新文档' } }
)

await Model.updateMany() 返回具有 5 个属性的对象,详细可查阅文档

updateMany() 很相似。这两个方法之间的区别在于,updateOne() 将最多更新一个文档,而 updateMany() 将更新与过滤器匹配的每个文档。

您应该尽可能使用 save() 而不是 updateOne()updateMany()。但是,Model.updateOne()Model.updateMany() 有一些优点:

  • updateOne() 是原子的。如果使用 find() 加载文档,它可能会在 save() 之前发生更改。
  • updateOne() 不需要您将文档加载到内存中,如果文档很大,这可能会给您带来更好的性能。

使用 Document.updateOne()

Document.updateOne() 方法是 Model.updateOne() 的语法糖。如果您已经将文档保存在内存中,那么 doc.updateOne() 将为您构建一个 Model.updateOne() 调用。

// 加载文档
const doc = await ArticleModel.findOne({ name: 'lio-zero' })

// 使用 Document.updateOne() 加载文档等同于 ArticleModel.updateOne({ _id: doc._id }, update)
const update = { title: '使用 findOne() 方法更新文档' }
await doc.updateOne(update)

const updatedDoc = await ArticleModel.findOne({ name: 'lio-zero' })
updatedDoc.title // '使用 findOne() 方法更新文档'

通常,Document.updateOne() 很少有用。最好使用 save()Model.updateOne() 用于 save() 不够灵活的情况。

使用 Model.findOneAndUpdate()

Model.findOneAndUpdate() 方法或其变体 Model.findByIdAndUpdate() 的行为类似于 updateOne():它们以原子方式更新与第一个参数 filter 匹配的第一个文档。与 updateOne() 不同的是,它会返回更新的文档。

const doc = await ArticleModel.findOneAndUpdate(
  { name: 'lio-zero' },
  { title: '使用 findOneAndUpdate() 方法更新文档' },
  { returnDocument: 'before' }
)

doc.title // '使用 findOneAndUpdate() 方法更新文档'

returnDocument 返回更新后的文档。它有两个可能的值:'before''after'。默认行为是 'before',这意味着返回文档在应用更新之前的状态。

returnDocument 出现之前,有两个类似的选项:returoriginalnew。它们都是布尔值,和 returnDocument 有着相同的效果,但 mongoose 建议我们使用最新的 returnDocument

总结

通常,除非需要原子更新,否则应该使用 save() 更新 Mongoose 中的文档。以下是更新文档的所有 4 种方法的主要功能摘要:

Atomic内存中的文档返回更新的文档更改跟踪
Document.save()
Model.updateOne()
Model.updateMany()
Document.updateOne()
Model.findOneAndUpdate()
  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Mongoose是一个在Node.js中操作MongoDB数据库的对象模型工具。它提供了一种简单而优雅的方式来定义和操作MongoDB中的文档Mongoose官方文档提供了详细的指南和API参考,帮助开发者了解和使用Mongoose。以下是Mongoose官方文档的主要内容: 1. 安装和配置:介绍了如何安装Mongoose以及配置连接MongoDB数据库的方法。 2. 模型定义:讲解了如何使用Mongoose定义模型,包括定义模式(Schema)和模型(Model)。 3. CRUD操作:介绍了如何使用Mongoose进行增删改查操作,包括创建文档、查询文档更新文档和删除文档。 4. 查询和过滤:详细介绍了Mongoose中的查询方法和过滤器,包括条件查询、排序、分页等。 5. 中间件:讲解了Mongoose中的中间件概念和使用方法,包括前置中间件、后置中间件和错误处理中间件。 6. 钩子函数:介绍了Mongoose中的钩子函数,可以在保存、更新等操作前后执行一些逻辑。 7. 数据验证:讲解了如何使用Mongoose进行数据验证,包括内置验证器和自定义验证器。 8. 引用和关联:详细介绍了Mongoose中的引用和关联概念,可以在不同集合之间建立关系。 9. 聚合查询:介绍了Mongoose中的聚合查询功能,可以进行复杂的数据聚合操作。 10. 插件:讲解了如何使用Mongoose插件扩展功能,以及一些常用的插件示例。 以上是Mongoose官方文档的主要内容,你可以通过访问Mongoose官方网站来获取更详细的信息和示例代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值