tl; dr
Ja, es ist möglich, mehrere Dokumente mit einem Feld zu nulldefinieren oder nicht zu definieren, während eindeutige "tatsächliche" Werte erzwungen werden.
Anforderungen :
- MongoDB v3.2 +.
- Kennen Sie Ihre konkreten Werttypen im Voraus (z. B. immer a
stringoder objectwenn nicht null).
Wenn Sie nicht an den Details interessiert sind, können Sie zum implementationAbschnitt springen .
längere Version
Um die Antwort von @ Nolan zu ergänzen, können Sie ab MongoDB v3.2 einen teilweise eindeutigen Index mit einem Filterausdruck verwenden.
Der Teilfilterausdruck weist Einschränkungen auf. Es kann nur Folgendes enthalten:
- Gleichheitsausdrücke (dh Feld: Wert oder Verwendung des
$eqOperators),
$exists: true Ausdruck,
$gt, $gte, $lt, $lteAusdrücke,
$type Ausdrücke,
$and Bediener nur auf der obersten Ebene
Dies bedeutet, dass der triviale Ausdruck {"yourField"{$ne: null}}nicht verwendet werden kann.
Unter der Annahme, dass Ihr Feld immer denselben Typ verwendet , können Sie einen $typeAusdruck verwenden .
{ field: { $type: <BSON type number> | <String alias> } }
MongoDB v3.6 hat Unterstützung für die Angabe mehrerer möglicher Typen hinzugefügt, die als Array übergeben werden können:
{ field: { $type: [ <BSON type1> , <BSON type2>, ... ] } }
Dies bedeutet, dass der Wert von einem von mehreren Typen sein kann, wenn dies nicht der Fall ist null.
Wenn wir also zulassen möchten, dass das emailFeld im folgenden Beispiel entweder stringoder beispielsweise binary dataWerte akzeptiert , wäre ein geeigneter $typeAusdruck:
{email: {$type: ["string", "binData"]}}
Implementierung
Mungo
Sie können es in einem Mungo-Schema angeben:
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"}}
}
}
});
oder fügen Sie es direkt der Sammlung hinzu (die den nativen node.js-Treiber verwendet):
User.collection.createIndex("email", {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
});
native mongodb treiber
mit collection.createIndex
db.collection('users').createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {
$type: "string"
}
}
},
function (err, results) {
// ...
}
);
Mongodb Muschel
mit db.collection.createIndex:
db.users.createIndex({
"email": 1
}, {
unique: true,
partialFilterExpression: {
"email": {$type: "string"}
}
})
Auf diese Weise können mehrere Datensätze mit einer nullE-Mail oder ohne E-Mail-Feld eingefügt werden, jedoch nicht mit derselben E-Mail-Zeichenfolge.