猫鼬不能使用字符串类型填充

Posted

技术标签:

【中文标题】猫鼬不能使用字符串类型填充【英文标题】:mongoose cannot populate using type String 【发布时间】:2016-05-23 15:28:50 【问题描述】:

所以我有这个带有字段的FacilityPersonnel 模型:

var field = 
    createdAt: type: Date, default: Date.now(),
    updatedAt: type: Date, default: Date.now(),

    some_id: type: String,
    fooAccessType: 
        type: String, 
        default: 'SuperAdmin', 
        ref: 'AccessType'
    ,  

我正在尝试在 控制器 上使用 populate fooAccessType

FacilityPersonnel.findOne(_id:req.params.id)
    .populate('fooAccessType')
    .exec(function (err, doc) 
        if (err)  res.status(500).json(err); return; ;
        res.status(200).json(doc);
    )

所有要查询的数据都是可用的,当我删除.populate('fooAccessType') 行时查询正在工作,但如果没有,我会返回此错误:


    "stack": "Error\n    at MongooseError.CastError ...",
    "message": "Cast to ObjectId failed for value \"SuperAdmin\" at path \"_id\"",
    "name": "CastError",
    "kind": "ObjectId",
    "value": "SuperAdmin",
    "path": "_id"

这是为什么呢?谢谢。

【问题讨论】:

只有当被引用的AccessType 模型的架构将_id 定义为字符串,并且有一个包含_id 的被引用文档包含该'SuperAdmin' 值时,这才有效。 我知道。谢谢@JohnnyHK 【参考方案1】:

目前,只有引用另一个集合的_idObjectId 值可以用作refs

这是一个讨论https://github.com/Automattic/mongoose/issues/2562

不过,它可能是未来的一项增强功能。


实际上,default 字段不需要添加 populate 值,只需定义 fooAccessType 如下

fooAccessType: 
    type: String, 
    ref: 'AccessType'
,  

对于population

FacilityPersonnel.findOne(_id:req.params.id)
    .populate('fooAccessType')
    .exec(

population中使用了ObjectIDObjectId是一个12字节的BSON类型,构造使用:

一个 4 字节的值,表示自 Unix 纪元以来的秒数,

一个 3 字节的机器标识符,

一个 2 字节的进程 ID,并且

一个 3 字节的计数器,从一个随机值开始。

所以SuperAdmin 不是一个正确的ObjectID。您可以使用UUID 作为ObjectID 的默认值

var uuid = require('node-uuid');

// ...
fooAccessType: 
    type: String, 
    default: uuid.v1, 
    ref: 'AccessType'
,  

但是,上面的代码很奇怪,fooAccesType 引用了AccessType 文档。

当尝试保存field文档时,首先要保存AccessType,然后从这个保存的AccessType中获取ObjectID并将其分配给fooAccessType,最终保存新的field文件。

var access = new AccessType();
access.save(function(err)
   if (err)
      // error handling
   else 
       facilityperson.fooAccessType = access._id;
       facilityperson.save(function(err) 

       );
   
);

对于population

FacilityPersonnel.findOne(_id:req.params.id)
    .populate('fooAccessType')
    .exec(

【讨论】:

那我该如何填充呢? @TheGreenFoxx,我认为没有必要给ref字段提供默认值。我已经更新了我的答案,如果我误解了你的问题,请原谅我。 嗨,我会试试这个。但我有理由为该字段添加默认值。这意味着fooAccessType 的值应该是“SuperAdmin”或“Creator”等...这就是为什么我使用字符串“SuperAdmin”作为人口的参考 ID。 @TheGreenFoxx,根据我的理解,ref 字段是文档的ObjectID,而不是您提到的superAdmin @TheGreenFoxx,请参阅此链接github.com/Automattic/mongoose/issues/2562,您的问题可以作为未来的一项改进来完成。【参考方案2】:
FacilityPersonnel.findOne(_id:req.params.id)
    .populate( path: "fooAccessType", model: "AccessType" )
    .exec()

【讨论】:

以上是关于猫鼬不能使用字符串类型填充的主要内容,如果未能解决你的问题,请参考以下文章

Graphql 结果不使用猫鼬填充关联类型的结果

我如何验证猫鼬自定义验证器中的类型

这个错误说明了啥?类型“ParsedQs”不可分配给类型“字符串”

国家电话代码前缀的猫鼬模式类型,例如“+44”

保存时使用字符串作为猫鼬模型的自定义 ID

更新混合类型的猫鼬嵌套数组