jmb*_*mer 52 mongoose mongodb node.js
我是node.js的新手,所以我有一种感觉,这将是我所忽略的愚蠢,但我找不到能够解决问题的答案.我要做的是创建一个路径,创建一个新的子对象,将其添加到父的子数组,然后将子对象返回给请求者.我遇到的问题是,如果我将字符串id传递给findById,节点崩溃了
TypeError:Object {}没有方法'cast'
如果我尝试传入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);
});
});
Run Code Online (Sandbox Code Playgroud)
如果我使用路径"/ myClass/51c35e5ced18cb901d000001/childClass/create"执行此代码,则这是代码的输出:
错误:CastError:对于路径"_id"{"path":"51c35e5ced18cb901d000001","instance":"ObjectID","validators":[],"setters":的值"[object Object]",Cast to ObjectId失败], "吸气剂":[], "_索引":空}
我尝试过使用findOne并传入{_id:id},但这似乎正是findById所做的.我已经尝试过在其他网站上列出的ObjectId的不同类.我试过调用ObjectId()就像一个函数而不是一个构造函数,并返回undefined.在这一点上,我已经没有想法,谷歌搜索答案似乎没有帮助.关于我做错了什么的任何想法?
另外,就像我说的,我是node/Mongo/Mongoose/Express的新手,所以如果有更好的方法来实现我的目标,请告诉我.我感谢所有的反馈.
编辑:
在Peter Lyons的解决方法之后,我搜索了我遇到的另一个错误,找到了findByIdAndUpdate,它按预期工作,完全符合我的希望.我仍然不确定为什么findById和findOne给我这样的问题而且我很想知道(可能需要提交错误报告),所以我会保留这个以防万一其他人有答案.
Pet*_*ons 63
简短回答:使用mongoose.Types.ObjectId.
Mongoose(但不是mongo)可以接受对象ID作为字符串并为你正确地"强制"它们,所以只需使用:
MyClass.findById(req.params.id)
Run Code Online (Sandbox Code Playgroud)
但是,需要注意的是,如果req.params.id不是mongo ID字符串的有效格式,则会抛出必须捕获的异常.
因此,要理解的主要问题是,mongoose.SchemaTypes只有在定义mongoose模式时才使用mongoose.Types的东西,以及在创建要存储在数据库或查询对象中的数据对象时使用的东西.所以mongoose.Types.ObjectId("51bb793aca2ab77a3200000d")工作,将为您提供一个可以存储在数据库中或在查询中使用的对象,如果给出一个无效的ID字符串,将抛出异常.
findOne获取查询对象并将单个模型实例传递给回调.并且findById字面上是一个包装器findOne({_id: id})(请参阅此处的源代码).只需find获取一个查询对象,并将匹配模型实例的数组传递给回调.
慢慢来吧.这令人困惑,但我可以保证你会感到困惑,而不是在猫鼬中遇到错误.它是一个非常成熟的库,但需要一些时间来掌握它.
我在你的代码片段中看到的另一个可疑的东西是new在实例化时不使用ChildClass.除此之外,您还需要发布架构代码,以便我们帮助您解决任何剩余的CastErrors.
gsa*_*edo 28
我遇到了这个错误,那是因为你要在_id字段中过滤的值不是ID格式,一个"if"应该解决这个问题.
const mongoose = require('mongoose');
console.log(mongoose.Types.ObjectId.isValid('53cb6b9b4f4ddef1ad47f943'));
// true
console.log(mongoose.Types.ObjectId.isValid('whatever'));
// false
Run Code Online (Sandbox Code Playgroud)
要解决此问题,请始终验证搜索的条件值是否为有效的ObjectId
const criteria = {};
criteria.$or = [];
if(params.q) {
if(mongoose.Types.ObjectId.isValid(params.id)) {
criteria.$or.push({ _id: params.q })
}
criteria.$or.push({ name: { $regex: params.q, $options: 'i' }})
criteria.$or.push({ email: { $regex: params.q, $options: 'i' }})
criteria.$or.push({ password: { $regex: params.q, $options: 'i' }})
}
return UserModule.find(criteria).exec(() => {
// do stuff
})
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
104771 次 |
| 最近记录: |