Mongoose:CastError:在路径“_id”处为值“\[object Object\]”转换为 ObjectId 失败

新手上路,请多包涵

我是 node.js 的新手,所以我觉得这将是我忽略的一些愚蠢的事情,但我一直无法找到解决我问题的答案。我要做的是创建一个路径,该路径将创建一个新的子对象,将其添加到父对象的子数组中,然后将子对象返回给请求者。我遇到的问题是,如果我将字符串 id 传递给 findById,节点会崩溃

类型错误:对象 {} 没有方法“强制转换”

如果我尝试传入一个 ObjectId ,我会得到

CastError:在路径“_id”处为值“[object Object]”转换为 ObjectId 失败

这是我的代码的粗略轮廓:

 var mongoose = require('mongoose');
var Schema = mongoose.Schema;
var ObjectId = Schema.ObjectId; //Have also tried Schema.Types.ObjectId, mongoose.ObjectId

mongoose.connect('mongodb://user:password@server:port/database');

app.get('/myClass/:Id/childClass/create', function(request, result) {
  var id = new ObjectId(request.params.Id);
  MyClass.findById(id).exec( function(err, myClass) {
    if (err || !myClass) { result.send("error: " + err + "<br>" + JSON.stringify(id) || ("object '" + request.params.Id + "' not found: " + id)); return; }
    var child = ChildClass();
    myClass.Children.addToSet(child);
    myClass.save();
    result.send(child);
  });
});

如果我使用路径“/myClass/51c35e5ced18cb901d000001/childClass/create”执行此代码,这是代码的输出:

错误:CastError:在路径“_id”{“path”:“51c35e5ced18cb901d000001”,“instance”:“ObjectID”,“validators”:[],“setters”:[ ],“getters”:[],”_index”:null}

我尝试使用 findOne 并传入 {_id:id} ,但这似乎正是 findById 所做的。我已经尝试过其他网站上列出的 ObjectId 的不同类。我试过像函数而不是构造函数一样调用 ObjectId() 并且返回未定义。在这一点上,我的想法已经用完了,而且谷歌搜索似乎没有帮助。关于我做错了什么的任何想法?

另外,就像我说的,我是 node/Mongo/Mongoose/Express 的新手,所以如果有更好的方法来实现我的目标,请告诉我。我感谢所有反馈。

编辑:

在 Peter Lyons 的解决方法之后,我搜索了另一个我遇到的错误并找到了 findByIdAndUpdate,它按预期工作并且完全符合我的期望。我仍然不确定为什么 findById 和 findOne 会给我这样的问题,我很想知道(可能需要提交错误报告),所以我会保持打开状态,以防其他人有答案。

原文由 jmblackmer 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 763
1 个回答

简短回答:使用 mongoose.Types.ObjectId

Mongoose(但不是 mongo)可以接受对象 ID 作为字符串并为您正确地“转换”它们,所以只需使用:

 MyClass.findById(req.params.id)

但是,需要注意的是,如果 req.params.id 不是 mongo ID 字符串的有效格式,则会引发您必须捕获的异常。

因此,要理解的主要令人困惑的事情是 mongoose.SchemaTypes 有你只在定义猫鼬模式时使用的东西,而 mongoose.Types 有你在创建要存储在数据库中的数据对象时使用的东西或查询对象。所以 mongoose.Types.ObjectId("51bb793aca2ab77a3200000d") 有效,将为您提供一个对象,您可以将其存储在数据库中或在查询中使用,如果给定的 ID 字符串无效,则会抛出异常。

findOne 采用查询对象并将单个模型实例传递给回调。并且 findById 实际上是 findOne({_id: id}) 的包装器( 参见此处的源代码)。只是 find 获取一个查询对象并将匹配模型实例的数组传递给回调。

慢慢来。这很令人困惑,但我可以向您保证,此时您会感到困惑,并且不会遇到猫鼬中的错误。这是一个相当成熟的库,但需要一些时间才能掌握它。

我在你的代码片段中看到的另一个可疑的事情是在实例化时没有使用 new ChildClass 。除此之外,您还需要发布您的模式代码,以便我们帮助您处理所有剩余的 CastErrors。

原文由 Peter Lyons 发布,翻译遵循 CC BY-SA 3.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题