【问题标题】:Mongoose, CastError: Cast to Array failed for value when trying to save a model that contains a modelMongoose,CastError:尝试保存包含模型的模型时,Cast to Array 的值失败
【发布时间】:2020-01-09 19:58:01
【问题描述】:

我正在尝试使用 mongoose 为我的 mongodb 数据库创建模型。这就是我想要做的:

var Class = mongoose.model('Class', {className: String, marks: [{type: Number}], grades: [{type: Number}]});
var User = mongoose.model('User', {email: String, classes: [Class] });


//Lets create a new user
var class1 = new Class({className: 'aaa', marks: [72, 88, 63], grades: [30, 40, 30]});
var user1 = new User({email: 'aaa@some.com', classes: [class1]});

保存class1 似乎可以正常工作,但是当我检查 mongodb 时,会显示:

{ 
  "_id" : ObjectId("someId"), 
  "className" : "TEST1234", 
  "grades" : [ 30, 40, 30 ], 
  "marks" : [ 72, 88, 63 ], 
  "__v" : 0 
}

"__v : 0" 是什么?

保存用户根本不成功,这是如下错误:

ValidationError: CastError: Cast to Array failed for value "{ 标记: [ 72, 88, 63 ], 等级:[ 30, 40, 30 ], _id: someId, className: 'TEST1234' }" 在路径 "classes" `

这个错误到底是什么意思?为什么要将任何东西投射到数组中? classes: [Class] 不应该是 class 类型的数组吗?

【问题讨论】:

    标签: node.js mongodb mongoose nosql


    【解决方案1】:

    伙计,我在创建这样的架构时遇到了类似的问题:

    QuestionnaireSchema = mongoose.Schema({
        formId: Number,
        name: String,
        questions: [
            {
                type: String,
                title: String,
                alternatives:[{
                    label: String,
                    value: "Mixed"
                }]
            }
        ]
    });
    

    我的错误是我使用“type”作为字段名,这是 mongoose 中的保留字。

    我只是改变:

    type: String,
    

    formType: String,
    

    这行得通。

    见:https://github.com/Automattic/mongoose/issues/1760

    【讨论】:

    • 你知道,我感觉你只是为我节省了几个小时的头发拉扯时间。谢谢!
    • 你先生,值得一个饼干
    • 为我工作!!谢谢:)
    • 或者,如果您想保留问题对象键“类型”,您可以使用下面的 Andrew Moores 答案。
    【解决方案2】:

    我在使用双嵌套模式的 mongoose 5.7.0+ 时遇到了类似的问题。

    除了它与关键字type 无关,而是一个猫鼬验证错误。

    https://github.com/Automattic/mongoose/issues/8472

    临时解决方法:将Schema.Types.Mixed 用于子架构

    【讨论】:

      【解决方案3】:

      允许在名为 type 的属性上显式定义类型规则,并且不会引发错误。像这样:

      type: {type: String}
      

      【讨论】:

      • 这是我的首选解决方案,而不是从“类型”更改我的密钥。
      【解决方案4】:

      仅供更新

      现在 Mongoose 支持子文档,这是嵌套数组的文档化方式,

      var arraySchema = new Schema({
          property: String
      });
      
      var objectSchema = new Schema({
          arrays: [arraySchema]
      });
      

      来源

      http://mongoosejs.com/docs/schematypes.html

      【讨论】:

        【解决方案5】:

        默认情况下,如果您的架构中有一个带有键“type”的对象,mongoose 会将其解释为类型声明。

        // Mongoose interprets this as 'loc is a String'
        var schema = new Schema({ loc: { type: String, coordinates: [Number] } });
        

        更改 typeKey:

        var schema = new Schema({
          // Mongoose interpets this as 'loc is an object with 2 keys, type and coordinates'
          loc: { type: String, coordinates: [Number] },
          // Mongoose interprets this as 'name is a String'
          name: { $type: String }
        }, { typeKey: '$type' }); // A '$type' key means this object is a type declaration
        

        链接:http://mongoosejs.com/docs/guide.html#typeKey

        【讨论】:

          【解决方案6】:

          尝试将类定义更改为:

          var classSchema = mongoose.Schema({className: String, marks: [{type: Number}], grades: [{type: Number}]});
          var userSchema = mongoose.Schema({email: String, classes: [classSchema] });
          var User = mongoose.model('User',userSchema);
          

          这是必需的,因为 mongoose 无法在没有相关架构的情况下解析对象。现在,当您为内部类对象创建新模式并在主 userSchema 中引用它时,猫鼬应该能够解析您的对象。

          【讨论】:

            【解决方案7】:

            你的模型定义不正确,你应该像下面这样修复。

            // var Schema = mongoose.Schema;
            var User = mongoose.model('User',{ 
              email: String, 
              classes: [ {type: Schema.Types.ObjectID, ref: 'Class'}] 
            });
            
            var Class1 = new Class({/*yourDataWillBeHere*/})
            
            Class1.save(function(err, classData) {
               var User1 = new User({/*YourDataWillBeHere*/})
               User1.classes.push(classData._id);
               User1.save(function(err, userData) {
                  //make something with userData object 
               })
            })
            

            然后你可以像这样使用populate()获取获取的数据

            User
            .find()
            .populate('classes')
            .exec()
            

            【讨论】:

            • 我似乎无法让它工作。TypeError: Invalid value for schema path 'type'var User = ... 我错过了什么?我取消了架构行的注释,并且我还在上面定义了 Class。
            猜你喜欢
            • 2018-01-31
            • 2021-01-31
            • 1970-01-01
            • 2019-02-17
            • 2022-07-12
            • 2020-10-21
            • 2021-01-07
            • 2021-06-05
            相关资源
            最近更新 更多