防止Mongoose中的updateAt变化findOneAndUpdate

时间:2019-02-15 21:19:02

标签: node.js mongoose

我先更新了猫鼬模型,然后使用实现简单视图计数器的$inc运算符进行检索:

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

Profile模式已启用timestamps选项。问题是updatedAtviewsCount更新期间被更新,这不是理想的行为。

我想在更新updatedAt时禁用viewsCount更新,最好通过执行尽可能少的查询。

我假设猫鼬的时间戳是通过预钩实现的。

findOneAndUpdate如何在不更新viewsCount的情况下递增updatedAt

可以否定时间戳挂钩的作用吗?

还有类似的问题可以解决updatedAt更新的问题,但是解决方案不适合这种情况。

3 个答案:

答案 0 :(得分:3)

在仔细研究过Mongoose文档之后,似乎简短的答案是否定的,没有设置findOneAndUpdate()字段就无法调用updatedAt。如果您查看文档here,则会清楚地指出所有用于更新的函数(findOneAndUpdate(),update()和bulkWrite())都会在查询中添加$set运算符以设置{{1 }}。话虽这么说,但您确实有另一种建议,我会极力推荐。

变通

直接将createdAt和UpdatedAt字段添加到模型中,并摆脱时间戳记。当然,Mongoose为您处理它确实很好,但是最后,如果您必须尝试更改特定用例的时间戳设置功能,则最好自己完成。

如果您喜欢在调用updatedAt.save()时设置了updatedAt和createdAt,则可以随时编写自己的中间件以添加操作。

.update()

我知道这不是理想的解决方案,但是坦率地说,我发现它更有用,因为它具有更好的控制力,并且猫鼬的意外行为更少。对自己的代码的控制越多越好。希望这会有所帮助!

答案 1 :(得分:3)

mongoose 5.9.3开始,您可以将第三个参数设置为{ timestamps: false }

来自docs

[options.timestamps = null]«Boolean»如果设置为false并且启用了模式级时间戳,请跳过此更新的时间戳。请注意,这使您可以覆盖时间戳。如果未设置架构级时间戳,则不执行任何操作。

答案 2 :(得分:1)

最简单的解决方法是直接与MongoDB API对话,而不让Mongoose处理更改。这段代码可以解决问题:

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