tl; dr
Ya, mungkin saja memiliki beberapa dokumen dengan bidang disetel ke null
atau tidak ditentukan, sambil menerapkan nilai "aktual" yang unik.
persyaratan :
- MongoDB v3.2 +.
- Mengetahui jenis nilai konkret Anda sebelumnya (misalnya, selalu a
string
atau object
jika tidak null
).
Jika Anda tidak tertarik dengan detailnya, silakan langsung ke implementation
bagian 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
$eq
operator),
$exists: true
ekspresi,
$gt
, $gte
, $lt
, $lte
Ekspresi,
$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 $type
ekspresi .
{ 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 email
bidang pada contoh di bawah ini untuk menerima salah satu string
atau, katakanlah, binary data
nilai, $type
ekspresi 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 null
email, atau tanpa bidang email sama sekali, tetapi tidak dengan string email yang sama.