为啥 mongoose 的 deleteOne 和 findById 对已删除的 id 起作用
Posted
技术标签:
【中文标题】为啥 mongoose 的 deleteOne 和 findById 对已删除的 id 起作用【英文标题】:Why deleteOne & findById of mongoose work on deleted id为什么 mongoose 的 deleteOne 和 findById 对已删除的 id 起作用 【发布时间】:2020-08-05 16:00:58 【问题描述】:目前正在使用 nodejs 开发与 MongoDB 数据库通信的 API,我注意到删除文档后的特殊行为。
确实,我的 API 有几个端点,允许检索数据库中的所有动物,使用相应的 id 检索特定的动物或删除特定的动物,再次使用要删除的文档的 id。
删除文档后会出现我不理解的结果。确实,如下图所示,当我删除名为“Johnny”的动物的文档时,通过其 ID 查找它或通过相同 ID 删除它的查询继续工作,即使 get 没有返回任何内容并且删除表示没有执行任何操作。
就我个人而言,我期望的行为与我为删除传递了错误的 id 相同(如下所示),但如果 id 已在数据库中分配,则即使在删除后查询也能正常工作。
MongoDB 是否有已删除文档的“缓存”,以便在意外删除时执行回滚?
您将在下面找到使用 find、deleteOne 和 findById 的不同端点
exports.getAllAnimal = (req, res, next) =>
Animal.find().sort('customer' : 1)
.then(animals => res.status(200).send(animals))
.catch(error => res.status(400).send( error: error.message ));
;
exports.getOneAnimal = (req, res, next) =>
Animal.findOne( _id: req.params.id )
.then(animal => res.status(200).send(animal))
.catch(error => res.status(400).send( error: error.message ));
;
exports.deleteAnimal = (req, res, next) =>
Animal.deleteOne( _id: req.params.id )
.then(thing => res.status(200).send( message : 'Animal successfully deleted'))
.catch(error => res.status(400).send( error: error.message ));
;
【问题讨论】:
【参考方案1】:MongoDB 不会在任何地方缓存已删除的 id。
问题是,当您说I passed a wrong id for a deletion ...
时,您传递的是一个长度相同但不是所需格式的 id。这就是 Mongoose 向您抛出错误的原因。
但是,如果你按照 MongoDB 的 id 结构创建一个数据库中不存在的 id 并对其进行操作,MongoDB 仍然会返回成功和空结果。
尝试使用5ea08034385a46666b05020f
并针对它运行.findById()
查询函数。它会成功返回一个空结果。
成功只表示操作成功,并不一定意味着它真的在数据库中找到了东西。
我无权访问您的数据库,因此 id 是随机生成的,但遵循以下 MongoDB ObjectId
规则:
12 字节的 ObjectId 值包括:
-
一个 4 字节的时间戳值,代表 ObjectId 的创建,以 为单位
自 Unix 纪元以来的秒数
一个 5 字节的随机值
一个 3 字节递增计数器,初始化为随机值
生成任意 MongoDB ObjectId: https://observablehq.com/@hugodf/mongodb-objectid-generator
【讨论】:
感谢您的澄清!我是否必须在我的 API 中将 String ID 与 ObjectID 对象切换? 那么您的项目到底想做什么?我只是有点困惑。 这只是诚实的尝试。我想管理一个动物数据库,仅此而已。我想知道是否在“getOneAnimal”和“deleteAnimal”中我必须制作 ObjectId(req.params.id) 而不仅仅是 req.params.id 当您尝试执行其他操作时,也许您可以为每个动物添加其他唯一标识符,例如自定义昵称或 id。因为ObjectId
仅严格保留给 MongoDB。那么你在req.params.id
中传递了什么?
Je suis français oui :) 好的,谢谢你的信息 :)以上是关于为啥 mongoose 的 deleteOne 和 findById 对已删除的 id 起作用的主要内容,如果未能解决你的问题,请参考以下文章