如果我有这样的架构:
var person = new Schema({
firstName: String,
lastName: String,
});
我想确保只有一个文档具有相同的firstName和lastName。
我该如何做到这一点?
答案 0 :(得分:79)
您可以使用模式上的index
调用来定义唯一的复合索引:
person.index({ firstName: 1, lastName: 1}, { unique: true });
答案 1 :(得分:4)
有趣的小事我最近才通过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)
我们的想法是创建一个在name
和user
上唯一的复合索引。这样,只要每个形状具有不同的名称,用户就可以创建任意数量的形状。并且逆转也应该是正确的 - 只要具有不同的用户,形状就可以具有相同的名称。对我来说,这样做并没有成功。
我注意到除_id
上的索引外,还创建了其他三个索引条目。 name
,user
和name_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)
查看作为结果创建的索引,我仍然可以看到三个索引 - name
,user
和name_user
。但不同的是,前两个不是唯一的,最后一个,即化合物。现在,每个用户使用多个不同形状的用例,或者具有不同用户的同名形状,就像冠军一样。
答案 2 :(得分:1)
这样定义您的架构
var person = new Schema({
firstName: String,
lastName: String,
index: true,
unique: true,
});
或
person.index({ firstName: 1, lastName: 1}, { unique: true });
答案 3 :(得分:0)
我没试过这个,但是使用一个独特的索引应该可以解决这个问题。
db.person.ensureIndex( { "firstname": 1, "lastname": 1 }, { unique: true } )
答案 4 :(得分:0)
const personSchema = new Schema({ firstName: String, lastName: String });
const person = mongoose.model('recipients', personSchema);
person.createIndexes();
您可能需要摆脱集合中的所有重复项,或者以更快,更简单的方式进行操作:
编辑代码,删除集合,然后重新启动Mongo。
答案 5 :(得分:0)
您可以这样定义自己的架构。
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 }
});