tl; dr
Ya, mungkin saja memiliki beberapa dokumen dengan bidang disetel ke nullatau tidak ditentukan, sambil menerapkan nilai "aktual" yang unik.
persyaratan :
- MongoDB v3.2 +.
- Mengetahui jenis nilai konkret Anda sebelumnya (misalnya, selalu a
stringatau objectjika tidak null).
Jika Anda tidak tertarik dengan detailnya, silakan langsung ke implementationbagian ini.
versi yang lebih panjang
Untuk melengkapi jawaban @ Nolan, dimulai dengan MongoDB v3.2 Anda dapat menggunakan indeks unik parsial dengan ekspresi filter.
Ekspresi filter parsial memiliki batasan. Ini hanya dapat mencakup yang berikut:
- persamaan persamaan (yaitu bidang: nilai atau menggunakan
$eqoperator),
$exists: true ekspresi,
$gt, $gte , $lt, $lteEkspresi,
$type ekspresi,
$and operator di tingkat atas saja
Ini berarti ungkapan sepele {"yourField"{$ne: null}}tidak dapat digunakan.
Namun, dengan asumsi bahwa bidang Anda selalu menggunakan tipe yang sama , Anda dapat menggunakan $typeekspresi .
{ field: { $type: <BSON type number> | <String alias> } }
MongoDB v3.6 menambahkan dukungan untuk menentukan beberapa jenis yang mungkin, yang dapat diteruskan sebagai array:
{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }
yang berarti bahwa ini memungkinkan nilai menjadi salah satu dari sejumlah tipe ganda jika tidak null .
Oleh karena itu, jika kita ingin mengizinkan emailbidang pada contoh di bawah ini untuk menerima salah satu stringatau, katakanlah, binary datanilai, $typeekspresi yang sesuai adalah:
{email: {$type: ["string", "binData"]}}
penerapan
luwak
Anda dapat menentukannya dalam skema luwak:
const UsersSchema = new Schema({
name: {type: String, trim: true, index: true, required: true},
email: {
type: String, trim: true, index: {
unique: true,
partialFilterExpression: {email: {$type: "string"}}
}
}
});
atau langsung tambahkan ke koleksi (yang menggunakan driver node.js asli):
User.collection.createIndex("email", {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
});
sopir mongodb asli
menggunakan collection.createIndex
db.collection('users').createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
},
function (err, results) {
// ...
}
);
cangkang mongodb
menggunakan db.collection.createIndex:
db.users.createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {$type: "string"}
}
})
Ini akan memungkinkan memasukkan beberapa catatan dengan nullemail, atau tanpa bidang email sama sekali, tetapi tidak dengan string email yang sama.