Mongoose 为 Number 字段接受 null

Posted

技术标签:

【中文标题】Mongoose 为 Number 字段接受 null【英文标题】:Mongoose accepts null for Number field 【发布时间】:2017-12-25 18:17:36 【问题描述】:

我有一个存储端口号的猫鼬模式。我还为该字段设置了默认值。

port:
    type:Number,
    default:1234

如果我没有通过我的 API 获得任何值,它将被设置为 1234。 但是,如果有人发送null,它会接受null 并保存到数据库中。

不应该将null 隐蔽为1234 吗? null 不是数字!我理解错了吗?

我正在考虑给定here 的解决方案,但我不想为没有它应该工作的东西添加额外的代码(除非我错了,它不应该将null 转换为1234

【问题讨论】:

它更像是一个javascript artifact,它是猫鼬中“类型”的基础。所以这取决于你是否可以简单地抛出一个异常(你可以用一个简单的验证器来做)或者用提供它的“默认”值代替null,正如你提到的那样,这是在“pre”钩子中完成的.或者确保输入是undefined 而不是null,然后“默认”就可以按预期工作。 下面的my answer 对您有帮助吗?有没有cmets? 【参考方案1】:

查看本期的cmets:

https://github.com/Automattic/mongoose/issues/2438

null 是 Date 属性的有效值,除非您指定要求。仅当值未定义时才设置默认值,而不是在其虚假时设置。

(它是关于日期的,但它也可以应用于数字。)

您的选择是:

在字段中添加required 添加会拒绝它的自定义验证器 使用挂钩/中间件解决问题

您可能会像这样使用预保存或验证后(或其他一些)挂钩:

YourCollection.pre('save', function (next) 
  if (this.port === null) 
    this.port = undefined;
  
  next();
);

但可能你必须使用类似的东西:

YourCollection.pre('save', function (next) 
  if (this.port === null) 
    this.port = 1234; // get it from the schema object instead of hardcoding
  
  next();
);

有关如何使null 在函数调用中触发默认值的一些技巧,另请参阅此答案:

Passing in NULL as a parameter in ES6 does not use the default parameter when one is provided

不幸的是,Mongoose 无法配置为将null 视为undefined(带有一些“非空”参数或类似的东西),因为有时您使用的数据是在请求为 JSON,它有时可以将 undefined 转换为 null:

> JSON.parse(JSON.stringify([ undefined ]));
[ null ]

甚至在没有(显式)undefined 的地方添加 null 值:

> JSON.parse(JSON.stringify([ 1,,2 ]));
[ 1, null, 2 ]

【讨论】:

好答案。谢谢:)【参考方案2】:

正如猫鼬官方文档here中所述

号码 要将路径声明为数字,您可以使用 Number 全局构造函数或字符串 'Number'。

const schema1 = new Schema( age: Number ); // age will be cast to a Number
const schema2 = new Schema( age: 'Number' ); // Equivalent
const Car = mongoose.model('Car', schema2);
There are several types of values that will be successfully cast to a Number.
new Car( age: '15' ).age; // 15 as a Number
new Car( age: true ).age; // 1 as a Number
new Car( age: false ).age; // 0 as a Number
new Car( age:  valueOf: () => 83  ).age; // 83 as a Number

如果您通过 valueOf() 函数传递一个返回数字的对象,Mongoose 将调用它并将返回的值分配给路径。

不强制转换 null 和 undefined 值。

NaN、转换为 NaN 的字符串、数组和没有 valueOf() 函数的对象都将导致 CastError。

【讨论】:

以上是关于Mongoose 为 Number 字段接受 null的主要内容,如果未能解决你的问题,请参考以下文章

从 mongoDB 集合中删除一个字段

如果字段设置为 null,则恢复为 mongoose 中的默认值

Mongoose:填充填充字段

Mongoose 选择子文档字段

Mongoose如何更新子文档字段?

Mongoose — 使用聚合创建具有 $sum 的新属性