mongodb(猫鼬)抛出E11000重复键错误集合

时间:2019-08-27 16:46:11

标签: node.js mongodb mongoose

我有一个状态模型,它是一个仅具有我设置为唯一名称的名称的查找,因为我不希望两个状态具有相同的名称。现在我有带状态属性的休假模型,该属性已设置为状态模式。错误E11000重复键错误集合在插入具有相同状态的第二个假期时插入第一个假期后引发。我知道mongodb会抛出异常,因为我已经有一个以state.name作为第一个假期的假期。

const stateSchema = new mongoose.Schema({
  name: {
    type: String,
    required: true,
    minlength: 1,
    maxlength: 30,
    unique: true
  }
});

const State = mongoose.model("State", stateSchema);

------------------------------------------------------

const vacationSchema = new mongoose.Schema({

-- some properties

  state: {
    type: stateSchema,
    required: true
  }

-- some properties

});

const Vacation = mongoose.model("Vacation", vacationSchema);

那么我该如何在状态集合中强制使用唯一的状态名称,但允许多个假期在假期状态中具有相同的状态?我必须显式地将状态:{type:stateSchema}更改为{type:new Schema(... etc吗?

1 个答案:

答案 0 :(得分:0)

您有两个选择:

  1. 如果State集合中只有一个字段 name ,并且它也保持不变(没有任何重命名/更改之类的内容),则每个休假文档仅包含一个州名那么您可以在假期文档中直接在状态字段中包含州名称值,如果您不想访问其他馆藏,这将有帮助每次您查询度假时,都无需维护两个集合。如果您要维护 State 集合,则没有必要直接在 Vacation 集合中存储名称,因为对于State集合中是否存在给定名称,将不会进行任何验证。不会,除非您在插入Vacation之前进行数据库调用以检查它,因为将数据存储到集合中是独立的-因此,您可能需要从unique : true中删除stateSchema,您的代码才能正常工作,如上所述代码是关于将数据存储到假期或只是在Vacation模式中将State设置为字符串并使用State模式将数据存储到State Collection中。

  2. 或者,如果您真的需要像现在一样维护另一个集合,则需要在 State 集合中的文档与 Vacation 中的文档之间建立映射。强>。如果大多数假期中的文档在数组字段中具有多个名称,这将很有帮助。州名在集合中是唯一的。最佳的联系方式是通过国家文件的_id。如果需要这样做,请在假期模式中进行更改,

    state: {
      type: [{ type: Schema.Types.ObjectId, ref: 'State' }],// you can make this single value instead of array.
      required: true
    }
    

    此后,您需要在读取时使用.populate()-参考:mongoose populate

    如果要将状态名称作为值存储在假期集合中,然后将状态字段设置为字符串,则可以在读取时使用.populate()-Ref:mongoose populate virtuals或类似名称到mongoDB的本机$lookup-参考:mongoDB $lookup

注意:

  1. 当您与州相关的事务时,州名称的唯一性会有所帮助,并且当您只需要频繁更改与州相关的数据+读取时还需要单独更改时,并且您仅需要与州或休假相关的数据时,就需要单独收集因为国家是独一无二的,所以可以使他们独立,您可以在假期中参考。
  2. 不仅在猫鼬模式中,您还可以在字段上创建unique索引,这样它将在数据库级别上,这在直接在数据库上或通过代码运行查询时有帮助,而猫鼬模式则通过代码触发,而且当您在现有馆藏上创建唯一索引并遇到问题时,意味着该字段已经存在重复数据。