更新子文档、NodeJS 和 Mongoose 的更有效方式

Posted

技术标签:

【中文标题】更新子文档、NodeJS 和 Mongoose 的更有效方式【英文标题】:More efficient way to update subdocuments, NodeJS and Mongoose 【发布时间】:2022-01-22 01:04:52 【问题描述】:

感谢阅读。我是新手,正在学习 mongoose,并试图围绕子文档更新。我可以更新子文档,但我使用的方法似乎不能很好地扩展并且设置起来很麻烦,但它确实有效。我不想逐个字段更新,即城市、州、邮编、国家等。我想简单地替换已自动更新的字段。

// Sample Object

  addressType: 'home',
  street: '123 Easy Street',
  city: 'Somewhere',
  state: 'NA',
  zip: '90210',
  country: 'USA'


// Schema
const userSchema = mongoose.Schema(billingProfile: [billingProfileSchema], orders: [orderSchema], timestamps: true, strict: false)


// Updating item by item works, BUT doesn't scale
const billingProfile = await User.findOneAndUpdate(_id:req.user._id, "billingProfile._id":req.params.billingProfileID, $set: "billingProfile.$.city" : req.body.city, new:true)

我在逻辑上想要的是以下内容,但它会导致错误...

// Setting req.body equal to ".$" results in an error
const billingProfile = await User.findOneAndUpdate(_id:req.user._id, "billingProfile._id":req.params.billingProfileID, $set: "billingProfile.$" : req.body, new:true)
    
Updating the path 'billingProfile.$.updatedAt' would create a conflict at 'billingProfile.$'

我认为应该可行的方法显然行不通。我希望有人可以帮助我以更有效的方式更新子文档。谢谢你:)

仅供参考 - 我正在使用"mongoose": "^6.1.1"

【问题讨论】:

【参考方案1】:

这是因为 mongoose 架构 timestamps: true 选项,更新发生时会自动设置 updatedAt 字段。

另一种方法是手动管理 billingProfileSchema 的 createdAtupdatedAt

或者只为 billingProfileSchema 设置 timestamps: false

【讨论】:

这很有趣,显然您提供的解决方案有效,但我有点困惑。我认为在 findByIdAndUpdate 方法中, save() 将处理 updateAt 方法,但我在 Mongoose 的逻辑中遗漏了一些东西。是否有任何文件可以说明这一点?感谢您对此的帮助:)

以上是关于更新子文档、NodeJS 和 Mongoose 的更有效方式的主要内容,如果未能解决你的问题,请参考以下文章

NodeJS - 我们可以从 Mongoose 更新填充的子文档吗?

NodeJS Mongoose 更新文档

如何在 Mongoose 中更新/更新文档/数据? Passport MongoDB、Express、AngularJS、Nodejs

使用 Mongoose 查找子文档字段部分匹配给定条件的文档

使用 Mongoose 查找子文档字段部分匹配给定条件的文档

如何在 Mongoose 中增加子文档的属性?