【问题标题】:How to construct a custom validator that makes a MongoDB field required if another field is a particular value?如果另一个字段是特定值,如何构造一个使 MongoDB 字段成为必需的自定义验证器?
【发布时间】:2020-07-14 02:05:35
【问题描述】:

我正在使用 MongoDB 和 Mongoose。

假设我有以下架构。

const notificationMetaSchema = new mongoose.Schema({
    listingId: { type: mongoose.Schema.Types.ObjectId },
});

const notificationSchema = new mongoose.Schema({
    category: { type: String, required: true, enum: [ "categoryA", "categoryB" ] },
    meta: notificationMetaSchema,
});

我希望我的“listingId”字段仅在“category”字段为“categoryA”时才需要。

此验证理想地存在于文档创建和更新期间。

如何构造自定义验证器来实现此效果?

编辑

我尝试了以下方法:

const notificationSchema = new mongoose.Schema({
    category: { type: String, required: true, enum: [ "categoryA", "categoryB" ] },
    meta: {
        listingId: {
            type: mongoose.Schema.Types.ObjectId,
            required: function () {
                return [
                    "categoryA",
                ].includes(this.category);
            }
        },
    },
});

但是,当我调用以下查询时:

Notification.findOneAndUpdate({}, $set: { category: "categoryA", meta: {} }).exec();

不抛出验证错误

【问题讨论】:

标签: mongodb mongoose


【解决方案1】:

您可以为 mongoose 架构中的字段编写一个 JavaScript 函数,该函数可以充当自定义验证器,您的架构应该如下所示:

const notificationSchema = new mongoose.Schema({
  category: {
    type: String,
    required: true,
    enum: ["categoryA", "categoryB"]
  },
  meta: {
    listingId: {
      type: mongoose.Schema.Types.ObjectId,
      required: function checkRequiredOrNot() {
        /** This function returns true or false, 'this.category' will retrieve current object's 'category' value */
        return this.category == "categoryA" ? true : false;
      }
    }
  }
});

【讨论】:

  • 我试了一下你的解决方案;但是,当我犯了无效错误时,我没有看到抛出错误,所以我不确定发生了什么。 (有关详细信息,请参阅我编辑的帖子)。
  • @user8888 :它将与.save() 完美配合,但一般required 本身在.findOneAndUpdate() 之类的调用中不会像预期的那样工作,请查看此参考:(stackoverflow.com/questions/31101984/…)。由于在您的情况下您没有直接的required,因此即使在$unset 期间它也不起作用,要使required 工作,您需要category 更新中不存在的值,请使用@987654330 @如果不是我可以建议的最后一件事是使用.save(),如果不能做其他事情,或者使用那里建议的一些包或joi验证。
  • 非常感谢您的详细解释。只是出于对我自己的学习/理解的好奇。有没有办法通过有一个单独的“元”模式来实现你的解决方案(如我原来的帖子所示)?我猜不是,因为“this”指的是“元”架构而不是“通知”架构?
  • @user8888 :是的,正确的this 指的是当前模式,因此您需要将元数据包装在原始模式本身中,可能还有其他我不知道的选项,但到目前为止这些是我们和我知道的选项:-)
猜你喜欢
  • 2018-02-28
  • 2019-05-15
  • 2015-03-01
  • 2017-05-22
  • 2012-02-09
  • 2021-04-20
  • 2017-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多