首页 > 解决方案 > MongooseJS - 插入子文档而不验证文档

问题描述

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

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

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

const mongoose = require('mongoose');

const requiredStringValidator = [
  (val) => {
    const testVal = val.trim();
    return testVal.length > 0;
  },
  // Custom error text
  'Please supply a value for {PATH}',
];
const childrenSchema = new mongoose.Schema({
  childId: {
    type: mongoose.Schema.Types.ObjectId,
  },
  firstName: {
    type: String,
    required: true,
    validate: requiredStringValidator,
  },
  lastName: {
    type: String,
    required: true,
    validate: requiredStringValidator,
  },
  birthday: {
    type: Date,
    required: true,
  },
});
const parentSchema = new mongoose.Schema(
  {
    parentId: {
      type: mongoose.Schema.Types.ObjectId,
    },
    firstName: {
      type: String,
      required: true,
      validate: requiredStringValidator,
    },
    lastName: {
      type: String,
      required: true,
      validate: requiredStringValidator,
    },
    children: [childrenSchema],
  },
  { collection: 'parentsjustdontunderstand' },
);
const mongooseModels = {
  Parent: 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"        }
    }
});

但是,当我按照猫鼬文档将子文档添加到数组并尝试通过猫鼬添加它时,它失败了。

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

{
    "firstName": "Will",
    "lastName": "Smith",
    "birthday": "9/25/1968"
}

我的代码是:

const { Parent } = require('parentsModel');
const parent = new Parent();
parent.children.push(req.body);
parent.save();

我得到的是:

ValidationError: Parent validation failed: firstName: Path `firstName` is required...`

它列出了所有文档的验证要求。

我可以在我做错的事情上使用一些帮助。作为记录,我在 Stackoverflow 上查看了这个答案:Push items into mongo array via mongoose但我看到的大多数示例都没有在他们的 Mongoose 模型中显示或讨论验证。

编辑 1

根据@jf 的反馈,我将代码修改为以下(将主体移出req.body并在代码中创建它以用于测试目的。当我尝试以推荐的方式推送更新时,记录被插入,但是,我仍然得到向控制台抛出验证错误:

const parent = await Parent.findOne({firstName: 'Willard'});
const child = {
  children: {
      "firstName": "Will",
      "lastName": "Smith",
      "birthday": "9/25/1968"
  }
}
parent.children.push(child);
parent.save();
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.

标签: javascriptnode.jsmongodbmongoose

解决方案


回答

@JF 是正确的,我错了。

这是不正确的:

const child = {
  children: {
      "firstName": "Will",
      "lastName": "Smith",
      "birthday": "9/25/1968"
  }
}

这是正确的:

const child = {
    "firstName": "Will",
    "lastName": "Smith",
    "birthday": "9/25/1968"
}

记录被插入数据库并保存,但由于我将其作为 PUT 请求启动,因此在使用HTTP 200 OK. 下面是整个解决方案的正确代码,但是,请记住,res.status代码仅在这种情况下是必需的,因为我是通过 PUT 请求模仿代码。

猫鼬型号:

const mongoose = require('mongoose');

const requiredStringValidator = [
  (val) => {
    const testVal = val.trim();
    return testVal.length > 0;
  },
  // Custom error text
  'Please supply a value for {PATH}',
];
const childrenSchema = new mongoose.Schema({
  childId: {
    type: mongoose.Schema.Types.ObjectId,
  },
  firstName: {
    type: String,
    required: true,
    validate: requiredStringValidator,
  },
  lastName: {
    type: String,
    required: true,
    validate: requiredStringValidator,
  },
  birthday: {
    type: Date,
    required: true,
  },
});
const parentSchema = new mongoose.Schema(
  {
    parentId: {
      type: mongoose.Schema.Types.ObjectId,
    },
    firstName: {
      type: String,
      required: true,
      validate: requiredStringValidator,
    },
    lastName: {
      type: String,
      required: true,
      validate: requiredStringValidator,
    },
    children: [childrenSchema],
  },
  { collection: 'parentsjustdontunderstand' },
);
const mongooseModels = {
  Parent: mongoose.model('Parent', parentSchema),
  Children: mongoose.model('Children', childrenSchema),
};
module.exports = mongooseModels;

以下是req.body

{
    "firstName": "Will",
    "lastName": "Smith",
    "birthday": "9/25/1968"
}

代码是:

const { Parent } = require('parentsModel');
const parent = await Parent.findOne({firstName: 'Willard'});
parent.children.push(req.body);
parent.save((err, doc) => {
  if (err) {
    res.status(500).json({
      message: 'Error finding active projects',
      error: err,
    });
  } else {
    res.status(200).json(doc);
  }
});

推荐阅读