tl; dr
Ja, es ist möglich, mehrere Dokumente mit einem Feld zu null
definieren 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
string
oder object
wenn nicht null
).
Wenn Sie nicht an den Details interessiert sind, können Sie zum implementation
Abschnitt 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
$eq
Operators),
$exists: true
Ausdruck,
$gt
, $gte
, $lt
, $lte
Ausdrü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 $type
Ausdruck 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 email
Feld im folgenden Beispiel entweder string
oder beispielsweise binary data
Werte akzeptiert , wäre ein geeigneter $type
Ausdruck:
{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 null
E-Mail oder ohne E-Mail-Feld eingefügt werden, jedoch nicht mit derselben E-Mail-Zeichenfolge.