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
非常相似。
但是,使用其他选项时存在一些差异:
query
、sort
、doc
(更新对象)、options
和一个 callback
。 findOneAndDelete 只需要 3 个(filter
或查询,options
和一个 callback
)
options
代表 findAndModify
包括 w
、wtimeout
和 j
代表写问题,如:
“从 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.remove
和findOneAndDelete
使用(collection.deleteOne
或collection.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 不工作 MERN 堆栈
node - DeprecationWarning: Mongoose: `findOneAndUpdate()` and `findOneAndDelete()` without the `us