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

标签 node.js mongodb mongoose

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

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/

相关文章:

c - mongodb c api无插入无错误

node.js - mongoose:按 id 排序

javascript - Mongoose populate() 返回对象数组而不是单个对象

javascript - Node.js 为相关查询提供空数组

javascript - 如何使用 jQuery 动态添加包含 EJS 的页面元素?

python - 为什么我的远程 MongoDB 连接需要对每个查询进行身份验证?

node.js - Mongoose 条件查询 - Case when like 语句

json - util.inspect/JSON.stringify 不适用于对象中的数组

javascript - MongoDB,从数组中删除对象

javascript - '类型错误 : undefined is not a function' using Protractor