findOneAndDelete() 和 findOneAndRemove() 之间的区别

Posted

技术标签:

【中文标题】findOneAndDelete() 和 findOneAndRemove() 之间的区别【英文标题】:Difference between findOneAndDelete() and findOneAndRemove() 【发布时间】:2018-11-09 03:39:57 【问题描述】:

我无法区分mongoose documentaion 中的findOneAndDelete() 和findOneAndRemove()。

Query.prototype.findOneAndDelete()

此函数与 Model.findOneAndRemove() 稍有不同之处在于 findOneAndRemove() 成为 MongoDB findAndModify() 命令,如 反对 findOneAndDelete() 命令。对于大多数猫鼬用例, 这种区别纯粹是迂腐的。 您应该使用 findOneAndDelete() 除非你有充分的理由不这样做。

【问题讨论】:

“你应该使用 findOneAndDelete() 除非你有充分的理由不” 理由是什么? findOneAndDelete() 执行 MongoDB findOneAndDelete() 命令,findOneAndRemove() 执行 MongoDB findAndModify() 命令 如果 "findOneAndRemove() 最终从集合中删除文档,为什么会执行 MongoDB findAndModify()"? 他们为什么说“除非你有充分的理由不使用,否则你应该使用 findOneAndDelete()” 它不是“最终从集合中删除文档”,它使用带有remove: true选项的findAndModify命令从集合中删除文档马上。 【参考方案1】:

TLDR:您应该使用 findOneAndDelete(),除非您有充分的理由不这样做。


更长的答案:

来自 findOneAndDelete 的 Mongoose 文档:

此函数与 Model.findOneAndRemove() 略有不同,因为 findOneAndRemove() 变成了 MongoDB findAndModify() 命令,而不是 findOneAndDelete() 命令。对于大多数猫鼬用例,这种区别纯粹是迂腐的。除非您有充分的理由不这样做,否则您应该使用 findOneAndDelete()。

Mongoose Docs findOneAndDelete

【讨论】:

【参考方案2】:

在 MongoDB 本地客户端(Mongoose 不同)中,将 remove: true 传递给findAndModify 使其删除找到的文档,在这种情况下它的行为看起来与findOneAndDelete 非常相似。 但是,使用其他选项时存在一些差异:

findAndModify 有 5 个参数:querysortdoc(更新对象)、options 和一个 callback。 findOneAndDelete 只需要 3 个(filter 或查询,options 和一个 callback

options 代表 findAndModify 包括 wwtimeoutj 代表写问题,如:

“从 MongoDB 请求的对独立 mongod 或副本集或分片集群的写入操作的确认级别。”或简单地保证可用于报告写入操作成功的级别。

options for findOneAndDelete 不包括写关注配置。

findAndModify 允许您返回新文档并同时将其删除。

例子:

// Simple findAndModify command returning the new document and
  // removing it at the same time
  collection.findAndModify(b:1, [['b', 1]], $set:deleted: Date(), remove:true, calback)

【讨论】:

我认为这些差异实际上并不存在。 (1) findOneAndDelete 确实采用了排序选项。 (2) findOneAndDelete 采用 writeConcern 选项,但 it's not documented。 (3)findOneAndDelete也返回被移除的文档。 是 @ZachB findOneAndDelete() 也返回删除文档(如果有的话)【参考方案3】:

除了 findOneAndRemove 使用带有 remove 标志的 findAndModify 和时间复杂度会比 findOneAndDelete 高一些,它们几乎相似,因为你正在更新。删除总是更快。

【讨论】:

这两个函数通过网络向 MongoDB 发送完全相同的命令。时间复杂度没有区别。 他们不会根据猫鼬文档发送相同的命令:mongoosejs.com/docs/api.html#model_Model.findOneAndDelete 另外请查看 MongoDB 文档:docs.mongodb.com/manual/reference/method/…docs.mongodb.com/manual/reference/method/… 根据我的经验,当您删除大量数据时,您会看到这两个命令之间的延迟,因为 findAndModify 返回数据 看我的回答。驱动程序转换命令。两者都返回数据。 "FindOneAndDelete() 查找匹配的文档,将其删除,并将找到的文档(如果有)传递给回调。"根据 mongoose 文档 findOneAndDelete 也会返回已删除的文档(如果有)。【参考方案4】:

这是确切的区别(引自 Model.findOneAndDelete() 部分中的猫鼬文档):

"此函数与 Model.findOneAndRemove() 略有不同之处在于 findOneAndRemove() 成为 MongoDB findAndModify() 命令,如 反对 findOneAndDelete() 命令。对于大多数猫鼬用例, 这种区别纯粹是迂腐的。你应该使用 findOneAndDelete() 除非你有充分的理由不这样做。”

这里是它的链接: https://mongoosejs.com/docs/api.html#model_Model.findOneAndDelete

【讨论】:

对于实物信息 findOneAndDelete() 也返回已删除的文档。【参考方案5】:

这里的其他答案有很多错误信息。它们的所有意图和目的都相同,您应该只使用findOneAndDelete()

Mongoose 的 Model.findOneAndRemove(query) 变为 MongoDB 的 findAndModify(query, remove: true)

Mongoose 的 Model.findOneAndDelete() 变为 MongoDB 的 findOneAndDelete()。但是,MongoDB 驱动程序将findOneAndDelete(query, opts) 转换为findAndModify(query, remove: true) (src)。因此,它们在数据库中执行完全相同的操作。

两者都采用相同的选择。

两者都返回已删除的文档。

【讨论】:

【参考方案6】:

在 mongoose 中 findOneAndDelete 的工作方式与 findOneAndRemove 相同。它们都通过 JSON 中的属性来查看对象,然后继续删除它,并在删除后返回它一次对象。当您使用本机 mongodb 作为数据库时,findOneAndDelete 可能对您有用,但在 mongoose 的情况下,我可能会建议您使用 findOneAndDelete 根据最新的 mongoose 和 nodejs 配置执行您的操作。 https://github.com/Automattic/mongoose/issues/6880

【讨论】:

我从上面进入github讨论DeprecationWarning: collection.remove is deprecated. Use deleteOne, deleteMany, or bulkWrite instead.你想说,findOneAndRemove使用collection.removefindOneAndDelete使用(collection.deleteOnecollection.deleteMany)?【参考方案7】:

findOneAndRemove 返回已删除的文档,因此,如果您删除了稍后决定不应删除的文档,则可以将其重新插入数据库。在删除文档之前确保您的逻辑是合理的,而不是在 IMO 之后进行检查。

findOneAndDelete 具有可用于影响更新哪个文档的排序参数。它还有一个 TimeLimit 参数,可以控制必须在哪个操作内完成

【讨论】:

两者都返回删除的文档。两者都有一个排序参数。两者都有时间限制。【参考方案8】:

我建议你使用 findOneAndDelete()。 Mongoose 提供了使用 ORM 处理数据的功能以及直接写入数据库的功能,findOneAndDelete() 是后者之一。直接写入数据库更危险,因为您冒着不调用中间件或验证器的风险,可能会向数据库提交部分或不完整的数据。请注意,我说它更多危险,并不是说它完全危险,findOneAndDelete() 只是贯穿整个 ORM,增加了安全性。

【讨论】:

两者都通过 Mongoose(ORM)并具有相同的中间件警告。

以上是关于findOneAndDelete() 和 findOneAndRemove() 之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

弃用警告:collection.findAndModify 已弃用。改用 findOneAndUpdate、findOneAndReplace 或 findOneAndDelete?

Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the `useFindAndModify

findOneAndDelete Mongoose 不工作 MER​​N 堆栈

node - DeprecationWarning: Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the `us

MongoDB 弃用警告

DiscordJS 编辑现有嵌入