Node.js 如何在Mongoose模式中验证对象键和值?

Node.js 如何在Mongoose模式中验证对象键和值?,node.js,mongodb,mongoose,schema,Node.js,Mongodb,Mongoose,Schema,在我的猫鼬模式中,我试图模拟一个字典offersInCategory,它看起来像这样: offersInCategory = { "Electronics": 2, "Furniture": 5 }; Mongoose不支持字典,因此我不得不在数组中使用对象文本,如下所示: offersInCategory: [{ category: { type: String, enum: ['Furniture', 'Household', 'Electronicts', 'Oth

在我的猫鼬模式中,我试图模拟一个字典
offersInCategory
,它看起来像这样:

offersInCategory = { "Electronics": 2, "Furniture": 5 };
Mongoose不支持字典,因此我不得不在数组中使用对象文本,如下所示:

offersInCategory: [{
  category: {
    type: String, 
    enum: ['Furniture', 'Household', 'Electronicts', 'Other']
  },
  val: {
    type: Number, 
    min: 0
  }
}]
我对这种方法的问题是它感觉不直观。此外,它不会阻止我的模型为同一类别创建多个条目,因此:

offersInCategory = [ { category: "Furniture", val: 2 }, { category: "Furniture", val: 0} ]
理想情况下,我的offersInCategory属性的结构如下:

offersInCategory : {
  "Furniture" : 0, 
  "Electronics" : 4 
}
但我不知道如何限制它,以便只有某些键可以分配给
offersincategray
对象(有点像键的枚举,而不是值),而没有重复项。我也不知道如何确保我的限制键的值是特定范围内的数字。如何做到这一点?

选项1(带“字典”): 您可以使用
对象
构造函数作为SchemaType来使用对象而不是对象数组。以下是一个适用于您的情况的示例:


如果您对此进行测试,它将删除数组中具有重复键的对象(保留较早的一个),并检查数组是否仅包含具有唯一
类别
键的对象。

太棒了,谢谢!第一种选择正是我想要的:)@DavidTamrazov没问题,我很乐意帮忙<代码>对象猫鼬上允许的类型@安德烈
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 }
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
  }
}]