tl; dr
Tak, możliwe jest posiadanie wielu dokumentów z polem ustawionym null
lub niezdefiniowanym, przy wymuszaniu unikalnych „rzeczywistych” wartości.
wymagania :
- MongoDB v3.2 +.
- Znajomość z wyprzedzeniem swoich konkretnych typów wartości (np. Zawsze
string
lub object
kiedy nie null
).
Jeśli nie interesują Cię szczegóły, możesz przejść do implementation
sekcji.
dłuższa wersja
Aby uzupełnić odpowiedź @ Nolana, zaczynając od MongoDB v3.2, możesz użyć częściowego unikatowego indeksu z wyrażeniem filtru.
Wyrażenie filtra częściowego ma ograniczenia. Może zawierać tylko:
- wyrażenia równościowe (np. pole: wartość lub za pomocą
$eq
operatora),
$exists: true
wyrażenie,
$gt
, $gte
, $lt
, $lte
Wyrażenia,
$type
wyrażenia,
$and
operator tylko na najwyższym poziomie
Oznacza to, że {"yourField"{$ne: null}}
nie można użyć trywialnego wyrażenia .
Jednak zakładając, że Twoje pole zawsze używa tego samego typu , możesz użyć $type
wyrażenia .
{ field: { $type: <BSON type number> | <String alias> } }
W MongoDB v3.6 dodano obsługę określania wielu możliwych typów, które mogą być przekazywane jako tablica:
{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }
co oznacza, że pozwala, aby wartość była dowolnego z wielu typów, gdy nie null
.
Dlatego, jeśli chcemy, aby email
pole w poniższym przykładzie akceptowało jedną string
lub, powiedzmy, binary data
wartości, odpowiednim $type
wyrażeniem byłoby:
{email: {$type: ["string", "binData"]}}
realizacja
mangusta
Możesz to określić w schemacie mangusty:
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"}}
}
}
});
lub bezpośrednio dodaj go do kolekcji (która używa natywnego sterownika node.js):
User.collection.createIndex("email", {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
});
natywny sterownik mongodb
za pomocą collection.createIndex
db.collection('users').createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
},
function (err, results) {
// ...
}
);
mongodb shell
używając db.collection.createIndex
:
db.users.createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {$type: "string"}
}
})
Umożliwi to wstawianie wielu rekordów z null
wiadomością e-mail lub bez pola adresu e-mail, ale nie z tym samym ciągiem wiadomości e-mail.