node.js - Mongoose:CastError:在路径 "[object Object]"的值 "_id"转换为 ObjectId 失败

标签 node.js mongodb mongoose

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

TypeError: Object {} has no method 'cast'

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

CastError: Cast to ObjectId failed for value "[object Object]" at path "_id"

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

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”执行此代码,这是代码的输出:

error: CastError: Cast to ObjectId failed for value "[object Object]" at path "_id" {"path":"51c35e5ced18cb901d000001","instance":"ObjectID","validators":[],"setters":[],"getters":[],"_index":null}

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

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

编辑:

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

最佳答案

简答:使用 mongoose.Types.ObjectId

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

MyClass.findById(req.params.id)

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

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

findOne接受一个查询对象并将一个模型实例传递给回调。和findById实际上是 findOne({_id: id}) 的包装(see source code here)。只需find接受一个查询对象并将匹配的模型实例数组传递给回调。

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

我在您的代码段中看到的另一个可疑之处是未使用 new实例化时 ChildClass .除此之外,您需要发布您的架构代码,以便我们帮助您找出任何剩余的 CastErrors。

关于node.js - Mongoose:CastError:在路径 "[object Object]"的值 "_id"转换为 ObjectId 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17223517/

相关文章:

mysql - Bluemix 使用 Node-RED 绑定(bind)到现有的 ClearDB MySQL 服务

javascript - sails .js : Add custom instace method result as a model property

node.js - 如何在 node.js 中使用 redis 进行身份验证?

node.js - 在 Node 中返回大量数据的良好实践

MongoDB嵌套对象字段深度限制

node.js - Windows Node : always get either "Error: ENOENT: no such file or directory, open" or "Error: EACCES: permission denied, open"

mongodb - 仅返回查询条件为 True 的文档中的键

java - 使用 Reactive MongoDB 模板返回 Mono<UpdateResult>

javascript - 如何格式化作为对象数组中值的日期

javascript - 在 Node.js 和 Mongoose 中从二进制重新创建图像