gpt4 book ai didi

node.js - Mongoose - 子文档验证不起作用

转载 作者:IT老高 更新时间:2023-10-28 13:26:11 25 4
gpt4 key购买 nike

我有一个如下所示的架构:

var minderSchema = mongoose.Schema({
phones: {type: [{
details: {
type: {
country_code: { type: String, required: true },
region_code: { type: String, required: true },
number: { type: Number, required: true }
},
required: true
},
}], required: true},
})

也就是说……一个minder由一系列电话(这是必需的)组成。每部电话都必须有国家代码、地区代码和号码。然而,验证似乎不起作用。 IE。我可以创造:

var minder = new Minder({
"phones": [{
details: {
number: "3343434"
}
}]
});

这应该不起作用,因为它缺少国家代码和地区代码。事实上,我可以像这样创建一个文档:

var minder = new Minder({
"phones": [{
details: {
"sdf":"sdf"
}
}]
});

它会验证。

我错过了什么概念?

最佳答案

这里的问题主要在于您如何在此处构建“详细信息”条目。因此,尽管您认为您可能已经做了什么,但实际上这里的条目类型是一个普通的子文档,或者通常被称为“散列/映射或字典”,具体取决于您最熟悉的术语。

严格来说,这些都不是以任何方式“键入”的,因此无法真正控制您放置在其中的“键”。所以你可能想要的是实际上可以以严格类型的方式构造的东西,例如:

var mongoose = require('mongoose');
var Schema = mongoose.Schema;

mongoose.connect('mongodb://localhost/test');

var phonesSchema = new Schema({
country_code: { type: String, required: true },
region_code: { type: String, required: true },
number: { type: String, required: true }
});

var minderSchema = new Schema({

phones:[phonesSchema]

});


var Minder = mongoose.model( 'Minder', minderSchema );

var minder = new Minder({
"phones": [{ "number": "12345", "bill": "45678" }]
});

console.log( JSON.stringify( minder, undefined, 2 ) );


minder.save();

这不仅分离了模式定义(方便且干净),而且现在您有了一个明确定义的“子类型”,可以在其中对条目执行验证。如果需要,您可以对此进行扩展,但我通常认为这是更简洁的形式。

这里最后一个重要的一点是了解“验证”实际发生的位置。因此,从您的示例中,您只是在创建实例,但这不是发生验证的地方。这实际发生的唯一地方是对象实例被“保存”并持久化到存储中。这允许您“构建”对象,但不是传统“类”意义上的对象的严格“验证器”。

所以运行上面的代码片段,你会得到这个输出:

{ _id: 537d7c71d4d04b65174d0c00,
phones: [ { number: '12345', _id: 537d7c71d4d04b65174d0c01 } ] }

events.js:72
throw er; // Unhandled 'error' event
^
No listeners detected, throwing. Consider adding an error listener to your connection.
ValidationError: Path `region_code` is required., Path `country_code` is required.
at model.Document.invalidate (/home/neillunn/node_modules/mongoose/lib/document.js:1009:32)
at EmbeddedDocument.invalidate (/home/neillunn/node_modules/mongoose/lib/types/embedded.js:178:19)
at /home/neillunn/node_modules/mongoose/lib/document.js:958:16
at validate (/home/neillunn/node_modules/mongoose/lib/schematype.js:610:7)
at /home/neillunn/node_modules/mongoose/lib/schematype.js:627:9
at Array.forEach (native)
at SchemaString.SchemaType.doValidate (/home/neillunn/node_modules/mongoose/lib/schematype.js:614:19)
at /home/neillunn/node_modules/mongoose/lib/document.js:956:9
at process._tickCallback (node.js:419:13)
at Function.Module.runMain (module.js:499:11)

注意到那里的“日志”输出保留了“有效”条目但丢弃了未定义的字段,然后“验证”实际上只发生在必填字段仅当对象实际上试图“保存”。

因此,请考虑您的结构以及验证到位后实际发生的情况。尝试添加未定义的字段不会出错,它只是丢弃。省略“必填”字段,仅在对象被持久化时才被检查,这使您有时间构建它。这些不是必需的“类构造函数”类型参数,而是用于不同的目的。


如果您真的想要嵌套,请删除“类型”声明,如下所示:

var phonesSchema = new Schema({
details: {
country_code: { type: String, required: true },
region_code: { type: String, required: true },
number: { type: String, required: true }
}
});

验证对你有用:

{
"_id": "537d9e6d5b433f8745547f52",
"phones": [
{
"_id": "537d9e6d5b433f8745547f53",
"details": {
"number": "12345"
}
}
]
}

events.js:72
throw er; // Unhandled 'error' event
^
No listeners detected, throwing. Consider adding an error listener to your connection.
ValidationError: Path `details.region_code` is required., Path `details.country_code` is required.

关于node.js - Mongoose - 子文档验证不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23797146/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com