Javascript MongooseJS-插入子文档而不验证文档

Javascript MongooseJS-插入子文档而不验证文档,javascript,node.js,mongodb,mongoose,Javascript,Node.js,Mongodb,Mongoose,我正在使用Mongoose和Javascript(NodeJS)来读/写MongoDB。我有一个文档(父文档),其中包含一堆子文档(子文档)。我的文档和子文档都在其模型中定义了验证(required:true,以及一个验证用户在字段中输入文本的函数) 当尝试将新的子文档推入数据库时,Mongoose拒绝我的推送,因为文档验证失败。这让我感到困惑,因为我并没有试图用子文档创建一个新文档,我只是试图将一个新的子文档推送到一个现有文档中 以下是我的(示例)猫鼬模型: const mongoose=re

我正在使用Mongoose和Javascript(NodeJS)来读/写MongoDB。我有一个文档(父文档),其中包含一堆子文档(子文档)。我的文档和子文档都在其模型中定义了验证(
required:true
,以及一个验证用户在字段中输入文本的函数)

当尝试将新的子文档推入数据库时,Mongoose拒绝我的推送,因为文档验证失败。这让我感到困惑,因为我并没有试图用子文档创建一个新文档,我只是试图将一个新的子文档推送到一个现有文档中

以下是我的(示例)猫鼬模型:

const mongoose=require('mongoose');
常量requiredStringValidator=[
(val)=>{
常量testVal=val.trim();
返回testVal.length>0;
},
//自定义错误文本
'请为{PATH}提供一个值',
];
const childrenSchema=new mongoose.Schema({
孩子:{
类型:mongoose.Schema.Types.ObjectId,
},
名字:{
类型:字符串,
要求:正确,
验证:requiredStringValidator,
},
姓氏:{
类型:字符串,
要求:正确,
验证:requiredStringValidator,
},
生日:{
类型:日期,
要求:正确,
},
});
const parentSchema=新的mongoose.Schema(
{
父ID:{
类型:mongoose.Schema.Types.ObjectId,
},
名字:{
类型:字符串,
要求:正确,
验证:requiredStringValidator,
},
姓氏:{
类型:字符串,
要求:正确,
验证:requiredStringValidator,
},
childrenSchema],
},
{集合:'parentsjustdontunderstand'},
);
const mongooseModels={
父:mongoose.model('Parent',parentSchema),
Children:mongoose.model('Children',childrenSchema),
};
module.exports=mongooseModels;
我可以通过以下MongoDB命令成功地将新的子文档推送到父文档中:

db.parentsjustdontunderstand.update({
    firstName: 'Willard'
}, {
    $push: {
        children: {
    "firstName": "Will",
    "lastName": "Smith",
    "birthday": "9/25/1968"        }
    }
});
但是,当我遵循Mongoose文档并尝试通过Mongoose添加它时,它失败了

出于测试目的,我使用Postman并对端点执行PUT请求。 以下是
req.body

{
“名字”:“遗嘱”,
“姓氏”:“史密斯”,
“生日”:“1968年9月25日”
}
我的代码是:

const{Parent}=require('parentsModel');
const parent=新父级();
父.子.推送(请求体);
parent.save();
我得到的回报是:

ValidationError: Parent validation failed: firstName: Path `firstName` is required...`
它列出了父文档的所有验证需求

在我做错的事情上,我需要一些帮助。为了记录在案,我在Stackoverflow上看到了这个答案:但我看到的大多数示例都没有显示或讨论Mongoose模型中的验证

编辑1

根据@j-f的反馈,我将代码修改为以下内容(将主体移出
req.body
,并在代码中创建它以进行测试。当我尝试按建议的方式推送更新时,会插入记录,但是,我仍然会将验证错误抛出控制台:

const parent=wait parent.findOne({firstName:'Willard'});
常量子项={
儿童:{
“名字”:“遗嘱”,
“姓氏”:“史密斯”,
“生日”:“1968年9月25日”
}
}
父。子。推(子);
parent.save();

您可以使用mongo查询将子对象推送到父对象中,因为在中,第一个对象是查找进行推送到的文档

语法类似于:
update({query},{update},{options})
。因此,您正在查找名为:
的文档:'Willard'
,并将子文档添加到其中

这里一切正常,所有字段都存在,父项存在于集合中,因此没有问题

但是使用

const parent=new parent();
父.子.推送(请求体);
parent.save();
父对象为空(除非构造函数填充所有字段,但我认为这不是一个好主意)

如果您尝试以下方法:

var parent=await model.findOne({firstName:'Willard'})
父.子.推送(请求体);
parent.save();
那就行了

在这种情况下,从集合中检索对象
父对象
,因此它包含所有必需的字段

我将编辑以更好地解释为什么两个查询不相同

基本上,您试图保存的子对象的结构与
db.collection.update
one不同。请注意,您创建的要插入到集合中的对象
child
只有一个名为
children
的属性。它没有必要的属性,如
firstName

我将使用纯JS来查看什么是
console.log()
输出并查看差异

您的mongo查询推送如下对象(翻译为js语言):

var数组=[]
array.push(
儿童={
“名字”:“遗嘱”,
“姓氏”:“史密斯”,
“生日”:“1968年9月25日”
}
)

console.log(数组)
答案

@J.F是对的,我错了

这是不正确的:

const child={
儿童:{
“名字”:“遗嘱”,
“姓氏”:“史密斯”,
“生日”:“1968年9月25日”
}
}
这是正确的:

const child={
“名字”:“遗嘱”,
“姓氏”:“史密斯”,
“生日”:“1968年9月25日”
}
记录被插入数据库并保存,但由于我是作为PUT请求启动此操作的,在使用
HTTP 200 OK
成功保存后,我没有正确响应。但是,请记住
res.status
代码仅在这种情况下是必需的,因为我是模仿的通过PUT请求重新输入代码

猫鼬模型:

const mongoose=require('mongoose');
常量requiredStringValidator=[
(五)
ValidationError: Parent validation failed: children.12.firstName: Path `firstName` is required., children.12.lastName: Path `lastName` is required., children.12.birthday: Path `birthday` is required.