如何validationMongoose模式中的对象键和值?

在我的Mongoose模式,我试图模拟字典offersInCategory看起来像这样:

 offersInCategory = { "Electronics": 2, "Furniture": 5 }; 

Mongoose不支持字典,所以我不得不在数组中使用对象字面值,如下所示:

 offersInCategory: [{ category: { type: String, enum: ['Furniture', 'Household', 'Electronicts', 'Other'] }, val: { type: Number, min: 0 } }] 

我用这种方法的问题是感觉不直观。 此外,它并不妨碍我的模型为同一类别创build多个条目,如下所示:

 offersInCategory = [ { category: "Furniture", val: 2 }, { category: "Furniture", val: 0} ] 

理想情况下,我会把我的offersInCategory属性的结构像这样:

 offersInCategory : { "Furniture" : 0, "Electronics" : 4 } 

但我不知道如何限制它,以便只有某些键可以分配给的offersInCategory对象(有点像键,而不是值的枚举types)没有重复。 我也不知道如何确保我的受限密钥的值是特定范围内的数字。 这怎么能做到呢?

选项1(带有“字典”):可以使用Object构造函数作为SchemaType来使用对象而不是对象数组。 这里是一个适用于你的情况的例子,使用SchemaType#validate

 offersInCategory: { type: Object, validate: object => { //our custom validator, object is the provided object let allowedKeys = ['Furniture', 'Household', 'Electronicts', 'Other']; let correctKeys = Object.keys(object).every(key => allowedKeys.includes(key)); //make sure all keys are inside `allowedKeys` let min = 5; let max = 10; let correctValues = Object.values(object).every(value => value > min && value < max); //make sure all values are in correct range return correctKeys && correctValues; //return true if keys and values pass validation } } 

这不适用重复的键检查,因为对象不能有重复的键 ,以后的键只是覆盖了以前的键:

 > let foo = { bar: 4, bar: 5} < Object { bar: 5 } 

正如你所看到的,早先分配的bar: 4键被后面的键覆盖。

选项2(带数组):您可以使用SchemaType#validate在某个文档path上实现您的自定义validation。 这是你想要的一个例子:

 offersInCategory: [{ validate: { validator: array => { //our custom validator, array is the provided array to be validated let filtered = array.filter((obj, index, self) => self.findIndex(el => el.category === obj.category) === index); //this removes any duplicates based on object key return array.length === filtered.length; //returns true if the lengths are the same; if the lengths aren't the same that means there was a duplicate key and validation fails }, message: 'Detected duplicate keys in {VALUE}!' } category: { type: String, enum: ['Furniture', 'Household', 'Electronicts', 'Other'] //category must be in this enum }, val: { type: Number, min: 0, //minimum allowed number is 0 max: 10 //maximum allowed number is 10 } }] 

如果你testing这个,它会摆脱与重复键(保持较早的)数组中的对象,并检查数组是否只包含具有唯一category键的对象。