如何用mongoose模式表示范围?

时间:2017-03-28 10:14:57

标签: javascript node.js mongodb mongoose

背景

让我们说我正在做一个你可以购买的水果模式。在此架构中,水果的价格范围为:

let fruit = {
    name: "banana",
    price: {
        currency: "EUR",
        range: [2, 10]
    }
};

要实现保存上述对象,我尝试使用以下架构:

let fruitSchema = {
    name: {type: String, required: true},
    price: {
        currency: {type: String, required: true},
        range: [{
            type: Number,
            min: 0
        }],
        validate: [arraySize]
    }
};

const arraySize = function arrayLimit(val) {
  return val.length === 2;
};

问题:

我对范围部分的解决方案感觉笨重,过于复杂,并且没有检查Max范围值是否大于Min范围值,即,不检查10> 2。

问题:

  • 您如何在mongoose中的架构中实现价格范围?

1 个答案:

答案 0 :(得分:2)

我的解决方案

我决定在我的Schema中分别使用这两个值,如下面的示例所示:

income: {
    currency: { type: String },
    range: {
        min: { type: Number, min: 0 },
        max: { type: Number, min: 0 }
    }
}

问题

然而,现在我有一个问题。如何在任何时候检查我的MAX >= MIN,以及MIN <= MAX ??

鉴于MIN和MAX都是强制性的,可以有一个只有较高范围的对象,或者只有较低的对象。

输入自定义验证器

要修复此验证问题,我使用了custom validator个函数。验证器是拼图中缺失的部分,并允许我强制执行最大和最小限制:

验证min的对象:

validate: {
    validator: function(val){
        const currMax = this.target.income.range.max;
        return (currMax !== undefined ? val <= currMax : true);
    },
    message: "The MIN range with value {VALUE} must be <= than the max range!"
}

验证对象的最大值:

validate: {
    validator: function(val) {
        const currMin = this.target.income.range.min;
        return (currMin !== undefined ? val >= currMin : true);
    },
    message: "The MAX range with value {VALUE} must be >= than the min range!"
}

最终结果

因此,最终结果如下:

income: {
    currency: { type: String },
    range: {
        min: { 
            type: Number, min: 0,
            validate: {
                validator: function(val){
                    const currMax = this.target.income.range.max;
                    return (currMax !== undefined ? val <= currMax : true);
                },
                message: "The MIN range with value {VALUE} must be <= than the max range!"
            }
        },
        max: { 
            type: Number, min: 0,
            validate: {
                validator: function(val) {
                    const currMin = this.target.income.range.min;
                    return (currMin !== undefined ? val >= currMin : true);
                },
                message: "The MAX range with value {VALUE} must be >= than the min range!"
            }
        }
    }
}

更进一步

这个解决方案很好,展示了先进的知识并满足了要求。在您尝试插入MIN > MAX的对象时,如果插入VALUE,您将收到一条很好的错误消息。

但是,我有以下问题/改进建议,我没有添加,因为我还不知道该怎么做:

  1. 验证程序将阻止插入不一致的对象。但是,当它不能防止错误的UPDATES时,即,以下示例将对MIN = 10的对象起作用:

    ObjModel.update( { _id: "58dd26b5476664e33eec4b93" }, { $set: {"income.range.max": 1}} );

  2. 要使用验证程序对对象进行更新,您必须使用save方法,并遵循mongoose docs末尾所述的约定。

    Model.findOne({ name: 'borne' }, function (err, doc){
      doc.name = 'jason borne';
      doc.visits.$inc();
      doc.save();
    });
    

    将按预期触发验证器。

    1. 在检查MIN和MAX的功能中,您可以使用{VALUE}打印要评估的值。但是,您可以使用该对象的其他值吗?比较MIN和MAX时,打印被评估的值以及要比较的值将非常有用。
    2. 希望它有所帮助,并激发灵感!