在未定义/空子文档 ObjectId 字段上设置值会产生 Cast to ObjectId 错误
Posted
技术标签:
【中文标题】在未定义/空子文档 ObjectId 字段上设置值会产生 Cast to ObjectId 错误【英文标题】:Setting a value on an undefined/null sub-document ObjectId field produces Cast to ObjectId error 【发布时间】:2015-04-25 19:24:50 【问题描述】:在 MEAN.js 应用程序中,我有一个包含子文档参考的架构:
var EmployeeSchema = new Schema(
supervisor:
type: Schema.Types.ObjectId,
ref: 'User',
,
...
无论是否设置主管字段,我都可以从架构创建模型。如果值是在创建时设置的,那么我可以像这样取消设置:
employee.supervisor = undefined;
employee.save(function(err)
...
但是,如果字段值已经未定义,那么此后我将无法设置任何值 - 这会产生以下错误:
CastError: Cast to ObjectId failed for value "[object Object]" at path "supervisor"
实际上,使用相同的 .save 代码路径再次尝试将该值设置为 undefined 会导致相同的错误。这个错误来自哪里?它所指的这个对象是什么(当我向它发送一个未定义的值时)?
我对猫鼬比较陌生。这感觉像是一个基本问题,很可能是用户错误。如果我没有使用正确的模式,请告诉我。我使用的是 mongoose 3.8.8,然后我搬到了 3.8.23,但无济于事。
编辑:可能很重要的一点是,当员工返回客户时,主管会被填充。使用 MEAN 样板快速控制器进行更新似乎存在问题,它将更改状态的 _.assign 分配给发送给客户端的 req.employee 数据。
如果我再次手动查询员工,并设置/取消设置主管字段,那么我能够获得预期的行为而不会出现错误。这包括设置为未定义,以及设置回一个有效值。所以它归结为人口 + 使用请求数据执行更新的组合。
【问题讨论】:
【参考方案1】:我认为这是因为 undefined 未通过 Schema.Types.ObjectId 验证。您应该使用 $unset
Employee.update(
//whatever query
,
$unset: supervisor: true
,
multi: true)
【讨论】:
根据link,未定义+保存相当于更新+未设置。不是这样吗?以上是关于在未定义/空子文档 ObjectId 字段上设置值会产生 Cast to ObjectId 错误的主要内容,如果未能解决你的问题,请参考以下文章
Mongoose:在设置值后,新创建的对象上的值转换为 ObjectId 失败 [重复]
Vue 警告我无法在未定义、null 或原始值上设置反应属性:null
Apollo graphql 正在为 mongodb 中的空子文档返回空数据
Apollo GraphQL 客户端“网络错误:在未定义的对象上找不到字段 XXXX”,disableOffline:false