如何使用嵌套的“类型”属性在 Mongoose 模式中定义非必填字段?

Posted

技术标签:

【中文标题】如何使用嵌套的“类型”属性在 Mongoose 模式中定义非必填字段?【英文标题】:How to define non-required field in Mongoose schema with nested "type" property? 【发布时间】:2020-05-21 13:01:49 【问题描述】:

我的项目中有以下 Mongoose 架构定义:

export const ProductSchema: SchemaDefinition = 
  type:  type: String, enum: constants.productTypes, required: true ,
  name:  type: String, required: false ,

  espData: 
    type:  type: String, required: true ,
    text:  type: String, required: true 
  ,

  error: 
    type: 
      message:  type: String, required: true ,
      statusCode:  type: Number, default: null 
    ,
    required: false
  
  // Some more definitions...
;

这里重要的是我收集了产品,其中每个产品都有自己的type(这是一个必需的字符串属性,可以在constants.productTypes 中定义值),一个非必需的name 字段和很快。此外,espData 字段具有自己的强制type 属性,这与***type 完全不同。而且,error 属性始终不存在,但当它存在时,它必须具有message 属性和可选的statusCode 属性。

我现在必须修改此架构,以便 espData 成为可选字段,因为我现在可能拥有不具有此属性的产品。我怎么做?我尝试了几件事,但都没有奏效:

首先,我修改了espData,使它看起来和error一样:
  espData: 
    type: 
      type:  type: String, required: true ,
      text:  type: String, required: true 
    ,
    required: false
  ,

但是,这不起作用,很可能是因为有太多嵌套的 type 属性。有趣的是,它完全适用于与espData 具有相同结构但没有嵌套type 属性的error 属性。我使用的代码是

    const model = new this.factories.product.model();
    model.type = 'hi-iq';
    // model.espData purposely left undefined
    await model.save();

我得到的错误是Product validation failed: espData.type.text: Path 'espData.type.text' is required., espData.type.type: Path 'espData.type.type' is required. 这表明从架构创建的model 被创建为espData.type.type,这不是我想要的(我想要espData.type)。

其次,我从上面尝试了相同的方法,只是没有使用required 字段,而是写了:default: null,这给了我一个错误TypeError: Invalid value for schema path 'espData.default', got value "null"

那么,如何将espData 定义为可选字段,当它存在时必须具有typetext 属性?

【问题讨论】:

【参考方案1】:

这就是你想要的。创建一个包含所有验证的新文档架构,并将其嵌套在另一个带有 required: false 的架构中(无论如何默认为 false)

const EspDataSchema = new Schema(
  type:  type: String, required: true ,
  text:  type: String, required: true ,
,
  
    _id: false,
  

);

例子


export const ProductSchema = new Schema(

...
   espData: 
    type: EspDataSchema,
    required: false
   ,

...

)

【讨论】:

是的,这是我需要的。我也尝试过这样的事情,但我没有使用new Schema()。我刚刚像这样提取EspDataSchemaconst EspDataSchema: SchemaDefinition = type: type: String, ...,这并没有真正起作用。谢谢!

以上是关于如何使用嵌套的“类型”属性在 Mongoose 模式中定义非必填字段?的主要内容,如果未能解决你的问题,请参考以下文章

在 Mongoose 变量中嵌套数据

如何在 mongoose 和 mongodb 中更新嵌套模型

如何使用 mongoose 填充具有无限嵌套级别的文档

Mongoose.js:嵌套属性的原子更新?

Mongoose:通过 findOneAndUpdate 查询使用嵌套对象数组的总和更新父子数据属性不起作用

Mongoose 可选嵌套属性 - 检查空/未定义?