【问题标题】:Mongoose schema optional with validationMongoose 模式可选,带验证
【发布时间】:2020-03-12 22:25:43
【问题描述】:

给定这样的架构:

new Schema(
    {
      someData: {
        someString: {
          required: false,
          maxlength: 400,
          type: String
        }
        otherData: {
          required: true,
          type: String
        }
});

someString 是可选的,但有一个验证来检查它的长度是否低于 400。

如果给我一个无效的长度字符串 (>400),这个对象是否仍会被保存但没有 someString 或者这会引发错误?如果这引发错误,我该如何更改架构以便仍然保存对象?

【问题讨论】:

    标签: mongodb validation mongoose


    【解决方案1】:

    不保存文档会报错。

    假设我们有这个架构:

    const mongoose = require("mongoose");
    const Schema = mongoose.Schema;
    
    const studentSchema = new Schema({
      someData: {
        someString: {
          required: false,
          maxlength: 5,
          type: String
        },
        otherData: {
          required: true,
          type: String
        }
      }
    });
    
    module.exports = mongoose.model("Student", studentSchema);
    

    还有这条发帖路线:

    const Student = require("../models/student");
    
    router.post("/students", async (req, res) => {
      try {
        const result = await Student.create(req.body);
        res.send(result);
      } catch (err) {
        console.log(err);
    
        if (err.name === "ValidationError") {
          return res.status(400).send(err.errors);
        }
        res.status(500).send("Something went wrong");
      }
    });
    

    当我们发送一个错误的请求时,它会给出 ValidationError,我们可以在其中读取来自err.errors 的错误详细信息。

    请求正文:

    {
      "someData": {
        "someString": "123456",
        "otherData": "other"
      }
    }
    

    响应将是:

    {
        "someData.someString": {
            "message": "Path `someData.someString` (`123456`) is longer than the maximum allowed length (5).",
            "name": "ValidatorError",
            "properties": {
                "message": "Path `someData.someString` (`123456`) is longer than the maximum allowed length (5).",
                "type": "maxlength",
                "maxlength": 5,
                "path": "someData.someString",
                "value": "123456"
            },
            "kind": "maxlength",
            "path": "someData.someString",
            "value": "123456"
        }
    }
    

    您可以通过删除maxlength 选项来解决此问题,或者检查路由中字段的长度,如果它的长度大于指定的最大长度,您可以对其进行substr,以免导致错误。

    router.post("/students", async (req, res) => {
      try {
        let doc = req.body;
    
        if (doc.someData && doc.someData.someString && doc.someData.someString.length > 5) {
          doc.someData.someString = doc.someData.someString.substring(0, 5);
        }
    
        const result = await Student.create(doc);
        res.send(result);
      } catch (err) {
        console.log(err);
    
        if (err.name === "ValidationError") {
          return res.status(400).send(err.errors);
        }
        res.status(500).send("Something went wrong");
      }
    });
    

    【讨论】:

    • 有没有办法让它真正可选?如 - 如果验证失败并且它是可选的仍然保存其余部分?
    • @K41F4r 我想可能有某种方式,顺便说一句,你为什么只删除maxlength 选项?
    • 一方面-我想限制该字段的输入,另一方面-我只需要它可用并且不会在数据库中占用太多空间
    • @K41F4r 如果字段的长度超过最大长度,您可以substr,这样不会发生错误并且该字段也被保存。
    • @K41F4r 我更新了答案以显示如果字段超过最大长度,如何子字符串。我想这是最好的方法。您可以将 maxlength 的值放入一个通用文件中,并在您的架构和路由中使用它,以便于管理。
    猜你喜欢
    • 2013-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-20
    • 2015-09-14
    • 1970-01-01
    • 2016-05-07
    • 2022-01-15
    相关资源
    最近更新 更多