【问题标题】:Saving to MongoDB using Mongoose fails on ObjectId as string使用 Mongoose 将 ObjectId 作为字符串保存到 MongoDB 失败
【发布时间】:2020-12-03 20:53:47
【问题描述】:

尝试使用 Mongoose/Joigoose 将我的对象保存到 MongoDB 时,我目前收到验证错误。架构的基本要点是一个简单的 Group 对象,它引用了父 Group 的 ObjectId (parent_group)。

这是错误: ValidationError: parent_group: Validator failed for path 'parent_group' with value '5f32d6c58d0c4a080c48bc79'

我的 Group 架构定义的代码如下所示:

// Imports (for reference)
const mongoose = require('mongoose'); // v5.9.29
const Joigoose = require('joigoose')(mongoose); // v7.1.2
const Joi = require('@hapi/joi'); // v17.1.1
const uniqueValidator = require('mongoose-unique-validator'); // v2.0.3
const ObjectId = mongoose.Schema.Types.ObjectId;

// Schema
const joiGroupSchema = Joi.object().keys({
    id: Joi.string().required().meta({ _mongoose: { unique: true }}).regex(/^[\w-]+$/).max(50),
    name: Joi.string().required().max(50),
    notes: Joi.string().allow(null),
    parent_group: Joi.string().allow(null).regex(/^[0-9A-Fa-f]*$/).max(24).meta({ _mongoose: { type: ObjectId, ref: 'Group' }}),
}).options({stripUnknown: true});

const groupSchema = new mongoose.Schema(Joigoose.convert(joiGroupSchema));
groupSchema.plugin(uniqueValidator);
const Group = mongoose.model("Group", groupSchema);

我的猫鼬保存调用如下所示:

// This code is inside of an Express HTTP POST definition (hence the result.value and req/res)
let model = new Group(result.value);
model.save(function (err, doc) {
    // On error
    if (err) {
        if (err.errors.id && err.errors.id.properties.type == 'unique') {
            res.status(409);
            return res.send('POST failed');
        }
        res.status(500);
        return res.send('POST failed');
    }
    res.status(200);
    return res.send('success');
});

我使用 Postman 传递的数据如下所示:

{
    "id": "asdf",
    "name": "ASDF",
    "notes": "postman",
    "parent_group": "5f32d6c58d0c4a080c48bc79"
}

我尝试了不同格式的 parent_group 字符串,尝试在使用 mongoose.Types.ObjectId("5f32d6c58d0c4a080c48bc79") 转换后通过 JS 传递它,但我一直收到相同的错误。我无法确定哪个验证器失败了,但这可能只是我不熟悉调试 Mongoose。

还有一点值得注意:

  • ObjectId 正确
  • null ObjectId 工作正常
  • model.save() 中捕获了错误

任何帮助将不胜感激!

【问题讨论】:

  • ValidationError 应该来自 joi/joigoose.. error.details 中的内容是什么?
  • @Matt 错误在 model.save() 中被捕获,所以除非 joi 为我的模式创建验证器,否则它似乎在猫鼬方面。唯一值得注意的是 errors.parent_group.properties 中的 type 和 kind 是“用户定义的”。
  • 看起来 joigoose 添加了 joi validator,但掩盖了 joi error。尝试针对 joiGroupSchema 验证入站对象。
  • @Matt 这很奇怪,因为在执行 Mongoose 调用之前我已经使用 joi 进行了验证,使用 joiGroupSchema 进行验证。 let result = joiGroupSchema.validate(req.body); if (result.error) ... 验证结果是我传递给 model.save() 的结果。

标签: javascript node.js mongodb mongoose


【解决方案1】:

我的 ObjectId 验证失败的原因是 joigoose adds joi validators to the Mongoose schema behind the scenes。无需深入研究,我的理解是当 joi 将 ObjectId 验证为字符串时,它通过了;在 Mongoose 将 ObjectId 转换为对象而不是字符串之后(正如 joi 验证器所期望的那样),这就是添加的验证器失败的地方。

由于向 Mongoose 架构添加 joi 验证器不是我想要的功能(我只是使用 joigoose 来整合架构),因此作为一种快速而简单的修复,我直接在我的本地副本中评论了 joigoose 中的该部分它。我目前正在使用patch-package 在我的应用程序中维护此补丁。

【讨论】:

    猜你喜欢
    • 2017-01-21
    • 2015-12-13
    • 2019-07-18
    • 2021-05-06
    • 2019-06-23
    • 1970-01-01
    • 1970-01-01
    • 2018-01-06
    • 1970-01-01
    相关资源
    最近更新 更多