【问题标题】:Mongoose: how to define a combination of fields to be unique?Mongoose:如何将字段组合定义为唯一?
【发布时间】:2013-04-10 07:35:02
【问题描述】:

如果我有这样的架构:

var person = new Schema({
  firstName:  String,
  lastName: String,
});

我想确保只有一个文件具有相同的名字和姓氏。

我怎样才能做到这一点?

【问题讨论】:

    标签: mongoose


    【解决方案1】:

    您可以在架构上使用 index 调用来定义唯一的复合索引:

    person.index({ firstName: 1, lastName: 1}, { unique: true });
    

    【讨论】:

    • @chovy 您不需要删除集合,但您需要删除字段上的任何现有复合索引。
    • 我没有现有的复合索引。但是即使在重新启动我的应用程序服务器之后,我也能够很好地(重复地)添加重复项。直到我放弃了收藏。
    • 这在第一次尝试时对我有用,无需以任何其他方式删除或修改集合
    • 只有满足独特要求时才会创建索引。这解释了为什么@chovy 不得不放弃他的收藏(可能只是删除重复项)
    • 要确定哪些重复项会阻止索引粘连,您可以这样做:Model.on('index', function(err) { console.log(err) });
    【解决方案2】:

    我最近才通过 Mongoose 的实验发现了一个有趣的小东西。例如,我有以下架构:

    const ShapesSchema = new mongoose.Schema({
      name: { type: String, required: true },
      user: { type: mongoose.Schema.Types.ObjectId, ref: 'User' }
    })
    
    ShapesSchema.index({ name: 1, user: 1 }, { unique: true })
    
    mongoose.model('Shapes', ShapesSchema)
    

    这个想法是创建一个在 nameuser 上唯一的复合索引。这样,只要每个形状都有一个不同的名称,用户就可以根据需要创建任意数量的形状。反过来也应该是正确的——形状可以有相同的名称,只要它们有不同的用户。对我来说不是这样。

    我注意到除了_id 上的索引之外,还创建了其他三个索引条目。 nameusername_user 各有一个,都设置为唯一。我对架构进行了修改,并将unique: false 包含到我用于复合索引的每个字段中,突然间一切都按预期工作了。我最终得到的是:

    const ShapesSchema = new mongoose.Schema({
      name: { type: String, required: true, unique: false },
      user: { type: mongoose.Schema.Types.ObjectId, ref: 'User', unique: false }
    })
    
    ShapesSchema.index({ name: 1, user: 1 }, { unique: true })
    
    mongoose.model('Shapes', ShapesSchema)
    

    查看作为结果创建的索引,我仍然看到三个索引 - nameusername_user。但不同之处在于,前两个不是唯一的,而最后一个是化合物。现在,我的每个用户使用多个不同形状的用例,或者具有不同用户的同名形状就像一个冠军。

    【讨论】:

    【解决方案3】:

    像这样定义你的架构

    
    var person = new Schema({
    firstName:  String,
    lastName: String,
    index: true,
    unique: true, 
    
    });
    
    

    
    person.index({ firstName: 1, lastName: 1}, { unique: true });
    
    

    【讨论】:

      【解决方案4】:
      const personSchema = new Schema({ firstName:  String, lastName: String });
      const person = mongoose.model('recipients', personSchema);
      person.createIndexes();
      

      您可能需要删除集合中的所有重复项,或者以更快更简单的方式进行:

      编辑您的代码,删除集合,然后重新启动 Mongo。

      【讨论】:

        【解决方案5】:

        我还没有尝试过,但是使用唯一索引应该可以解决问题。

        db.person.ensureIndex( { "firstname": 1, "lastname": 1 }, { unique: true } )
        

        【讨论】:

        • 这在猫鼬中没有实现
        • 对我来说猫鼬没有调用 ensureIndex 所以这对我有用,谢谢
        【解决方案6】:

        您可以像这样定义您的架构。

        const mongoose = require("mongoose");
        const Schema = mongoose.Schema;
        const bcrypt = require("bcryptjs");
        
            const userSchema = new Schema({
              firstName: {
                trim: true,
                type: String,
                required: [true, "firstName is required!"],
                validate(value) {
                  if (value.length < 2) {
                    throw new Error("firstName is invalid!");
                  }
                }
              },
              lastName: {
                trim: true,
                type: String,
                required: [true, "lastName is required!"],
                validate(value) {
                  if (value.length < 2) {
                    throw new Error("lastName is invalid!");
                  }
                }
              },
              username: {
                unique: [true, "Username already available"],
                type: String,
                required: [true, "Username is required"],
                validate(value) {
                  if (value.length < 10) {
                    throw new Error("Username is invalid!");
                  }
                }
              },
              mobile: {
                unique: [true, "Mobile Number alraedy available"],
                type: String,
                required: [true, "Mobile Number is required"],
                validate(value) {
                  if (value.length !== 10) {
                    throw new Error("Mobile Number is invalid!");
                  }
                }
              },
              password: {
                type: String,
                required: [true, "Password is required"],
                validate(value) {
                  if (value.length < 8) {
                    throw new Error("Password is invalid!");
                  }
                }
              },
              gender: {
                type: String
              },
              dob: {
                type: Date,
                default: Date.now()
              },
              address: {
                street: {
                  type: String
                },
                city: {
                  trim: true,
                  type: String
                },
                pin: {
                  trim: true,
                  type: Number,
                  validate(value) {
                    if (!(value >= 100000 && value <= 999999)) {
                      throw new Error("Pin is invalid!");
                    }
                  }
                }
              }
              date: { type: Date, default: Date.now }
            });
        

        【讨论】:

        • 这对firstName, lastName 的独特之处究竟是什么?
        猜你喜欢
        • 2011-01-13
        • 2016-09-11
        • 2012-08-27
        • 2015-09-07
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多