防止更新在Mongoose中发生更改时findOneAndUpdate

p1tboqfb  于 2023-10-19  发布在  Go
关注(0)|答案(3)|浏览(133)

我更新了Mongoose模型,然后使用$inc操作符检索,该操作符实现了简单的视图计数器:

const profile = await Profile.findOneAndUpdate({ userName }, { $inc: { viewsCount: 1 } });

Profile架构已启用timestamps选项。问题是updatedAtviewsCount更新期间更新,这不是一个理想的行为。
我想在viewsCount更新时禁用updatedAt更新,最好是尽可能少地执行查询。
我假设Mongoose时间戳是用pre-hook实现的。
findOneAndUpdate如何在不更新updatedAt的情况下递增viewsCount
这可以通过取消时间戳挂钩的效果来实现吗?
有类似的问题可以解决updatedAt更新的问题,但解决方案并不适合这种情况。

qacovj5a

qacovj5a1#

从mongoose 5.9.3开始,您可以将第三个参数设置为{ timestamps: false }
从文档中:
[options.timestamps=null] «Boolean»如果设置为false并且启用了架构级别的时间戳,则跳过此更新的时间戳。请注意,这允许您覆盖时间戳。如果未设置架构级别的时间戳,则不执行任何操作。

bjg7j2ky

bjg7j2ky2#

在浏览了Mongoose文档之后,似乎简短的答案是否定的,没有办法在不设置updatedAt字段的情况下调用findOneAndUpdate()。如果您查看这里的文档,它清楚地说明了所有用于更新的函数(findOneAndUpdate(),update()和bulkWrite())都将$set操作符添加到查询中以设置updatedAt。话虽如此,你确实有另一个选择,我强烈推荐。

变通办法

将createdAt和updatedAt字段直接添加到模型中,并去掉时间戳。当然,Mongoose为您处理它真的很好,但最后,如果您必须尝试更改特定用例的时间戳的设置功能,最好自己做。
如果您喜欢在调用.save().update()时设置updatedAt和createdAt,您可以编写自己的中间件来添加操作。

ProfileSchema.pre('save', function(next) {
  this.createdAt = Date.now();
  this.updatedAt = Date.now();
  next();
});

我知道这不是理想的解决方案,但坦率地说,我发现它更有用,因为有更大的控制,和更少的意外行为从 Mongoose 。你对自己的代码控制得越多越好。希望这对你有帮助!

ndh0cuux

ndh0cuux3#

我已经将createdAt设置为不可变。因此,即使我们在集合中编辑相关文档并使用new Date()设置updatedAt字段以获取当前时间戳,它也无法更新。对我来说效果很好。检查下面的代码片段。

createdAt: {
  type: Date,
  immutable: true,
  default: Date.now
},
updatedAt: {
  type: Date,
  default: new Date()
}

我把时间戳设为真。
请检查与上述代码片段相关的总架构。

const projectSchema = mongoose.Schema({
  name: {
    type: String,
    requied: true
  },
  description: {
    type: String,
    required: true
  },
  owner: {
    type: mongoose.Schema.Types.ObjectId,
    ref: "User"
  },
  createdAt: {
    type: Date,
    immutable: true,
    default: Date.now
  },
  updatedAt: {
    type: Date,
    default: new Date()
  }
}, {
  timestamps:true
});

相关问题