Mongoose:如何将字段组合定义为唯一的?

Mongoose:如何将字段组合定义为唯一的?,mongoose,Mongoose,如果我有这样一个模式: var person=新模式({ 名字:String, 姓氏:String, }); 我希望确保只有一个文档具有相同的名字和姓氏 我怎样才能做到这一点呢?我还没有尝试过,但使用唯一索引应该可以做到这一点 db.person.ensureIndex( { "firstname": 1, "lastname": 1 }, { unique: true } ) 您可以使用模式上的索引调用定义唯一的复合索引: person.index({firstName:1,lastNam

如果我有这样一个模式:

var person=新模式({
名字:String,
姓氏:String,
});
我希望确保只有一个文档具有相同的名字和姓氏


我怎样才能做到这一点呢?

我还没有尝试过,但使用唯一索引应该可以做到这一点

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

您可以使用模式上的
索引
调用定义唯一的复合索引:

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

我最近才通过实验猫鼬发现了一个有趣的小东西。例如,我有以下模式:

const shapeschema=new mongoose.Schema({
名称:{type:String,必需:true},
用户:{type:mongoose.Schema.Types.ObjectId,ref:'user'}
})
索引({name:1,user:1},{unique:true})
mongoose.model('Shapes',shapeschema)
其想法是创建一个复合索引,该索引在
name
user
上是唯一的。这样,用户可以创建任意多个形状,只要每个形状都有一个不同的名称。反之亦然——形状可以有相同的名称,只要它们有不同的用户。对我来说不是这样的

我注意到,除了
\u id
上的索引外,还创建了其他三个索引项。
name
user
name\u user
各一个,所有设置都是唯一的。我对模式进行了修改,并将
unique:false
包含到我用于复合索引的每个字段中,突然间,所有字段都按预期工作。我最终得到的是:

const shapeschema=new mongoose.Schema({
名称:{type:String,必需:true,unique:false},
用户:{type:mongoose.Schema.Types.ObjectId,ref:'user',unique:false}
})
索引({name:1,user:1},{unique:true})
mongoose.model('Shapes',shapeschema)

查看作为结果创建的索引,我仍然可以看到三个索引-
name
user
name\u user
。但区别在于,前两个并不是唯一的,而最后一个是化合物。现在,我的用例是每个用户有多个不同的形状,或者具有不同用户的相同名称的形状,就像一个champ一样工作。

这样定义您的模式


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

});

const personSchema=newschema({firstName:String,lastName:String});
const person=mongoose.model('recipients',personSchema);
person.createIndexes();
您可能需要清除集合中的所有重复项,或者以更快、更简单的方式执行此操作:

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


您可以这样定义您的模式

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 }
    });
const mongoose=require(“mongoose”);
const Schema=mongoose.Schema;
const bcrypt=require(“bcryptjs”);
const userSchema=新模式({
名字:{
特里姆:没错,
类型:字符串,
required:[true,“必须使用firstName!”,
验证(值){
如果(值.长度<2){
抛出新错误(“firstName无效!”);
}
}
},
姓氏:{
特里姆:没错,
类型:字符串,
必需:[true,“需要姓氏!”,
验证(值){
如果(值.长度<2){
抛出新错误(“lastName无效!”);
}
}
},
用户名:{
唯一:[true,“用户名已可用”],
类型:字符串,
必需:[true,“需要用户名”],
验证(值){
如果(值。长度<10){
抛出新错误(“用户名无效!”);
}
}
},
流动电话:{
唯一:[正确,“手机号码alraedy可用”],
类型:字符串,
必需:[true,“需要手机号码”],
验证(值){
如果(value.length!==10){
抛出新错误(“手机号码无效!”);
}
}
},
密码:{
类型:字符串,
必需:[true,“需要密码”],
验证(值){
如果(值。长度<8){
抛出新错误(“密码无效!”);
}
}
},
性别:{
类型:字符串
},
出生日期:{
类型:日期,
默认值:Date.now()
},
地址:{
街道:{
类型:字符串
},
城市:{
特里姆:没错,
类型:字符串
},
别针:{
特里姆:没错,
类型:数字,
验证(值){

如果(!(value>=100000&&value),这在mongoose中没有实现,因为mongoose没有调用ensureIndex,所以这对我有效thanks@chovy您不需要删除集合,但需要删除字段上的任何现有复合索引。我没有现有的复合索引。但我可以添加重复项(重复),即使在重新启动我的应用程序服务器之后也是如此。直到我删除了集合,这才开始。这在第一次尝试时对我有效,无需以任何其他方式删除或修改集合。只有在满足唯一要求的情况下,才会创建索引。这解释了@chovy必须删除其集合的原因(可以删除重复项)要确定哪些重复项阻止索引粘滞,您可以这样做:
Model.on('index',function(err){console.log(err)});
这对我帮助很大。我还需要添加
mongoose.connect(uri,{useCreateIndex:true});
,每个文档如下:
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 }
    });