如果我具有以下架构:
const userSchema = new mongoose.Schema({
modules: {
type: Map,
of: {
name: {
type: String,
required: true
}
}
}
})
从理论上讲,猫鼬在创建新文档时应验证每个UserModule
的类型,并确保存在必需的name
属性。
但是,如果我创建的用户使用的模块没有name
属性:
await User.create({ modules: { example: {} } })
没有引发错误。通常,猫鼬能够正确验证所需的类型。
我可以想到的解决方法包括对每个模块的密钥进行硬编码(并且不使用映射),或者在modules
映射上包括一个验证器,以检查所有模块是否都存在必需的密钥,而这些都不是理想。
是否有更好的方法来检查地图值的类型?
答案 0 :(得分:1)
您正在提供一个值...这是有效的Map定义:
await User.create({
modules: {
example: {} // <-- this is a valid. Key is `example` value is {}
}
})
据Map尚未验证。只有键始终是字符串,Map才会验证值。考虑以下模式:
var AuthorSchema = new Schema({
books: {
type: Map,
of: { type: Number },
default: { "first book": 100 }, // <-- set default values
required: true // <-- set required
}
})
// after mongoose.model('Author', AuthorSchema) etc ....
var author1 = new Author({ books: { 'book one': 200 } })
author1.save() // <-- On save this works
var author2 = new Author({ books: { 'book one': "foo" } })
author2.save() // <-- This fails validation with "Cast to number failed ..."
var author1 = new Author()
author1.save() // <-- default would set values and that would pass the `required` validation
如果您需要地图,请确保没有默认值等。
您也可以查看map
tests @ github以获得更多见识
在这些测试中,您还可以看到如何制作复杂的嵌套地图:
var AuthorSchema = new Schema({
pages: {
type: Map,
of: new mongoose.Schema({ // <-- just nest another schema
foo: { type: Number }, // <-- set your type, default, required etc
bar: { type: String, required: true } // <-- required!
}, { _id: false }),
default: {
'baz': {
foo: 100, bar: 'moo' // <-- set your defaults
}
}
}
})
这将按预期保存:
{
"_id" : ObjectId("5cf1cf4b7f67711963e2406d"),
"pages" : {
"baz" : {
"foo" : 100,
"bar" : "moo"
}
}
}
尝试保存此操作将失败,因为需要要求bar
:
var author = new Author({
"pages" : {
"baz" : { "foo" : 1 } // <-- no bar!
}
});