Mongoose, CastError: Cast to Array не удалось получить значение при попытке сохранить модель, содержащую модель.
Я пытаюсь создать модель для моей базы данных mongodb, используя mongoose. Это то, что я пытаюсь сделать:
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: '[email protected]', 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 "{ marks: [ 72, 88, 63 ], grades: [ 30, 40, 30 ], _id: someId, className: 'TEST1234' }" at path "classes"
Что именно означает ошибка? Почему это отличает массив от массива? Не должны ли classes: [Class]
быть массивом типа class
?
Ответы
Ответ 1
Человек, у меня была аналогичная проблема, создающая схему вроде этого:
QuestionnaireSchema = mongoose.Schema({
formId: Number,
name: String,
questions: [
{
type: String,
title: String,
alternatives:[{
label: String,
value: "Mixed"
}]
}
]
});
Моя ошибка заключалась в том, что я использую "тип" в качестве имени поля, и это зарезервированное слово в мангусте.
Я просто меняю:
type: String,
в
formType: String,
и это работает.
см.: https://github.com/Automattic/mongoose/issues/1760
Ответ 2
Попробуйте изменить определение класса:
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);
Это необходимо, так как мангуста не может анализировать объект без соответствующей схемы. Теперь, когда вы создаете новую схему для внутреннего объекта класса и ссылаетесь на нее в основном userSchema, mongoose должен иметь возможность анализировать ваш объект.
Ответ 3
Явное определение правила типа для свойства с именем type разрешено и не будет вызывать ошибку. как это:
type: {type: String}
Ответ 4
Ваше определение модели неверно, вы должны исправить это, как показано ниже.
// 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()
Ответ 5
Просто для обновления
Теперь Mongoose поддерживает поддокументы, которые являются документированным способом вложения массивов,
var arraySchema = new Schema({
property: String
});
var objectSchema = new Schema({
arrays: [arraySchema]
});
источники
http://mongoosejs.com/docs/schematypes.html
Ответ 6
По умолчанию, если у вас есть объект с ключом "type" в вашей схеме, mongoose интерпретирует его как объявление типа.
// Mongoose interprets this as 'loc is a String'
var schema = new Schema({ loc: { type: String, coordinates: [Number] } });
Изменение типаKey:
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