用户应该能够创建预订并选择公司联系他们的方式 - 电子邮件或电话或 Whatsapp,我不希望任何人通过预订发送垃圾邮件,因此这些是独特的值,我们不知道用户是哪个联系人将提供,因此我们需要能够将 null 作为值,并且仍然不会给出“重复键”错误
我尝试了here中的示例 - 它允许 null 作为唯一值,但也允许重复值,因此它不是解决方案 - 我的架构:
const BookingSchema = new mongoose.Schema({
fullName: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
},
email: {
type: String,
trim: true,
index: {
unique: true,
partialFilterExpression: {email: {$type: 'string'}},
},
set: v => (v === '' ? null : v),
},
phone: {
type: String,
trim: true,
index: {
unique: true,
partialFilterExpression: {phone: {$type: 'string'}},
},
set: v => (v === '' ? null : v),
},
whatsapp: {
type: String,
trim: true,
index: {
unique: true,
partialFilterExpression: {whatsapp: {$type: 'string'}},
},
set: v => (v === '' ? null : v),
},})
我找到了解决方案,这个特定的模式将只保留具有唯一字段的文档,同时将让保留该字段具有值:null,值:“”的文档,因此解决方案是您需要使用索引并描述它您想要的每个字段都是这样,也使用中间件有助于保留 null 和空值
const BookingSchema = new mongoose.Schema({
fullName: {
type: String,
required: true
},
createdAt: {
type: Date,
default: Date.now
},
message: {
type: String
},
status: {
type: Boolean,
required: true,
default: false
},
email: {
type: String,
unique: true,
sparse: true,
},
phone: {
type: String,
nique: true,
sparse: true,
},
whatsapp: {
type: String,
unique: true,
sparse: true,
},
messenger: {
type: String,
trim: true
}
})
BookingSchema.index(
{ email: 1 },
{ unique: true, partialFilterExpression: { email: { $exists: true } } }
)
BookingSchema.index(
{ phone: 1 },
{ unique: true, partialFilterExpression: { phone: { $exists: true } } }
)
BookingSchema.index(
{ whatsapp: 1 },
{ unique: true, partialFilterExpression: { whatsapp: { $exists: true } } }
)
BookingSchema.pre('save', function(next) {
if (this.email === null || this.email === "") {
this.email = undefined;
}
if (this.phone === null || this.phone === "") {
this.phone = undefined;
}
if (this.whatsapp === null || this.whatsapp === "") {
this.whatsapp = undefined;
}
next()
})