【问题标题】:findByIdAndDelete not finding the provided idfindByIdAndDelete 未找到提供的 ID
【发布时间】:2019-11-14 19:23:45
【问题描述】:

我正在尝试在模型上使用 Mongoose findByIdAndDelete() 方法,但它看不到需要删除的 _id

我的路线声明类似于这个(缩小的)示例:

router.delete('/delete-entity/:id', (req, res) => {
  Entity.findByIdAndDelete(req.params.id)
    .exec()
    .then((docs) => { ...handle success })
    .catch((err) => { ...handle error });
});

我只运行了与模型的保存方法挂钩的中间件。但是这个中间件并没有触及_id这个字段。

当我在路线内console.log() 时,我可以看到req.params.id 已设置。此外,如果我尝试使用其他字段来识别我的文档以删除它(所以不是 _id 字段),它确实有效。但是,当我尝试使用_id 字段时,返回给客户端的所有内容都是''。这让我相信在比较 _id 字段的数据类型时出了点问题。但是使用mongoose.Type.ObjectId() 也无济于事。

这里会发生什么?

除了这个已经提供的信息。这是我的模型。

const embeddedEntity = new mongoose.Schema({
  name: { type: String, required: true }
}, { _id: false });
const entity = new mongoose.Schema({
  name: { type: String, required: true },
  embeddedInfo: { type: embeddedEntity, required: true }
});
module.exports = mongoose.model('Entity', entity);

@Invider 我设法从探查器那里得到了这个。

{
        "op" : "command",
        "ns" : "development.entities",
        "command" : {
                "findAndModify" : "entities",
                "query" : {
                        "_id" : ObjectId("5dc95b8cc472d31232dba5a3")
                },
                "new" : false,
                "remove" : true,
                "upsert" : false,
                "lsid" : {
                        "id" : UUID("30086660-0619-440e-9268-148957428a2b")
                },
                "$db" : "development"
        },
        "keysExamined" : 0,
        "docsExamined" : 0,
        "ndeleted" : 0,
        "numYield" : 0,
        "locks" : {
                "Global" : {
                        "acquireCount" : {
                                "r" : NumberLong(1),
                                "w" : NumberLong(1)
                        }
                },
                "Database" : {
                        "acquireCount" : {
                                "w" : NumberLong(1)
                        }
                },
                "Collection" : {
                        "acquireCount" : {
                                "w" : NumberLong(1)
                        }
                }
        },
        "responseLength" : 74,
        "protocol" : "op_msg",
        "millis" : 0,
        "planSummary" : "IDHACK",
        "execStats" : {
                "stage" : "DELETE",
                "nReturned" : 0,
                "executionTimeMillisEstimate" : 0,
                "works" : 1,
                "advanced" : 0,
                "needTime" : 0,
                "needYield" : 0,
                "saveState" : 0,
                "restoreState" : 0,
                "isEOF" : 1,
                "invalidates" : 0,
                "nWouldDelete" : 0,
                "nInvalidateSkips" : 0,
                "inputStage" : {
                        "stage" : "IDHACK",
                        "nReturned" : 0,
                        "executionTimeMillisEstimate" : 0,
                        "works" : 1,
                        "advanced" : 0,
                        "needTime" : 0,
                        "needYield" : 0,
                        "saveState" : 0,
                        "restoreState" : 0,
                        "isEOF" : 1,
                        "invalidates" : 0,
                        "keysExamined" : 0,
                        "docsExamined" : 0
                }
        },
        "ts" : ISODate("2019-11-14T09:27:52.988Z"),
        "client" : "127.0.0.1",
        "allUsers" : [ ],
        "user" : ""
}

【问题讨论】:

  • A similar question,有帮助吗?
  • 在调用此路由时检查 mongo 运行的查询。调用路由后,您可以在 mongo 控制台中运行以下命令来获取它。 1.db.setProfilingLevel(2); 2.db.system.profile.find({ns: "mydb.myCollection"}).sort({createdAt: -1}).limit(1).pretty()
  • 您可以将您的实体模型添加到问题中吗?
  • 我不这么认为,但值得一试:)
  • 您确定要发送 req.params.id 中的现有 id 吗?

标签: node.js mongodb express mongoose


【解决方案1】:

非常感谢@invider 和@SuleymanSah 为我指明了正确的方向。

这个问题实际上很简单,我完全忽略了它,并且确实与我预期的数据类型有关。

我的 e2e 测试失败了,因为与尝试使用 Postman 调用路由相同的问题。

问题在于,在将测试样本添加到数据库时,我自己设置了 _id 字段。这很可能导致存储的值是string 类型。让 MongoDB 自己设置 _id 字段解决了这个问题。至少对于使用 Postman 在实时环境中工作而言。

对于我的 e2e 测试,我必须为每次测试修改将加载到数据库中的数据。我通过以下方式添加样本:

{
  _id: '5dc95b8cc472d31232dba5a5',
  name: 'SomeData',
  embeddedInfo: {
    name: 'someOtherData'
  }
}

我应该首先将 _id 转换为 ObjectId。像这样:

{
  _id: mongoose.Types.ObjectId('5dc95b8cc472d31232dba5a5'),
  name: 'SomeData',
  embeddedInfo: {
    name: 'someOtherData'
  }
}

再次。谢谢你们俩。

【讨论】:

  • 很高兴你成功了
猜你喜欢
  • 2017-07-09
  • 1970-01-01
  • 2014-10-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-29
  • 2021-02-03
相关资源
最近更新 更多