首页 > 解决方案 > 当我的默认数组为空时,为什么猫鼬会用空字符串调用我的验证器?

问题描述

我已将此行添加到我的架构中...

recentTags: {type:[String], default: [], validate: tagRegex}

这是我的标签验证正则表达式...

tagRegex: /^[a-z0-9#]+( *[a-z0-9\\/:\-()[\].?#]+)*$/

注意:它不允许空字符串,也不应该因为它不是有效的标签名称。

所以我的问题是,我所有触及该模式的测试现在都因这个 Mongo 错误而失败......

ValidationError: User validation failed: recentTags: Validator failed for path `recentTags` with value ``

我完全不明白它为什么要尝试运行我的验证器,为什么当值数组为空时它会这样做?为什么它传递一个空字符串?

请注意,我一直小心地重建我的测试数据库并等待所有索引完成,然后再运行我的测试,其余的工作正常。我的 Mongo 版本是 3.6.8,我的 Mongoose 版本是 ^5.9.25,都在节点 v14.11.0 上运行

标签: mongodbmongoose

解决方案


我相信验证器将正则表达式应用于整个字符串数组,并在应用正则表达式时隐式类型转换为字符串;一个空数组将被隐式类型转换为空字符串""


一个可能的解决方案

据我了解,您似乎是在验证数组中的每个单独元素之后,而不是整个数组值。使用元素级验证器可以更复杂地指定数组类型。

这是更改的示例:

const Tags = model("tags", new Schema(
    {
        recentTags: {
            type: [{
                type: String,
                validate: tagRegex,
            }],
            default: [],
        },
    },
));

以下是一些带有此验证的插入示例:

// valid, uses the default value
await Tags.insertMany([{}]);
// also valid, no elements are here so no validation is done
await Tags.insertMany([{recentTags: []}])
// also valid, the element passes the regex
await Tags.insertMany([{recentTags: ["test"]}])

// not valid, the element does not pass the regex
await Tags.insertMany([{recentTags: [""]}])

请参阅有关数组模式类型的文档:https ://mongoosejs.com/docs/schematypes.html


旁注

您可能还希望验证它recentTags实际上是一个数组或使用更复杂的自定义验证错误消息


推荐阅读