Ich habe mich gefragt, ob es eine Möglichkeit gibt, einen eindeutigen Sammlungseintrag zu erzwingen, aber nur, wenn der Eintrag nicht null ist . e Beispielschema:
var UsersSchema = new Schema({
name : {type: String, trim: true, index: true, required: true},
email : {type: String, trim: true, index: true, unique: true}
});
'email' ist in diesem Fall nicht erforderlich, aber wenn 'email' gespeichert ist, möchte ich sicherstellen, dass dieser Eintrag eindeutig ist (auf Datenbankebene).
Leere Einträge scheinen den Wert 'null' zu erhalten, sodass jeder Eintrag ohne E-Mail mit der Option 'einzigartig' abstürzt (wenn es einen anderen Benutzer ohne E-Mail gibt).
Im Moment löse ich es auf Anwendungsebene, würde aber gerne diese Datenbankabfrage speichern.
Vielen Dank
email
Feld, nicht dort, wo es tatsächlich einen Wert von hatnull
. Siehe aktualisierte Antwort.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 :
string
oderobject
wenn nichtnull
).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:
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 .MongoDB v3.6 hat Unterstützung für die Angabe mehrerer möglicher Typen hinzugefügt, die als Array übergeben werden können:
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 entwederstring
oder beispielsweisebinary data
Werte akzeptiert , wäre ein geeigneter$type
Ausdruck:Implementierung
Mungo
Sie können es in einem Mungo-Schema angeben:
oder fügen Sie es direkt der Sammlung hinzu (die den nativen node.js-Treiber verwendet):
native mongodb treiber
mit
collection.createIndex
Mongodb Muschel
mit
db.collection.createIndex
: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.quelle
unique
undsparse
). Ich habe mein Schema mit dieser Antwort aktualisiert, meinen vorhandenen Index gelöscht und es hat wie ein Zauber funktioniert.Nur ein kurzes Update für diejenigen, die dieses Thema erforschen.
Die ausgewählte Antwort funktioniert, Sie können jedoch auch Teilindizes verwenden.
Weitere Informationen zu Teilindizes: https://docs.mongodb.com/manual/core/index-partial/
quelle
Tatsächlich wird nur das erste Dokument, in dem "E-Mail" als Feld nicht vorhanden ist, erfolgreich gespeichert. Nachfolgende Speicherungen, bei denen "E-Mail" nicht vorhanden ist, schlagen fehl, während ein Fehler ausgegeben wird (siehe Codeausschnitt unten). Informationen dazu finden Sie in der offiziellen Dokumentation zu MongoDB in Bezug auf eindeutige Indizes und fehlende Schlüssel hier unter http://www.mongodb.org/display/DOCS/Indexes#Indexes-UniqueIndexes .
Per Definition kann mit einem eindeutigen Index nur ein Wert nur einmal gespeichert werden. Wenn Sie null als einen solchen Wert betrachten, kann er nur einmal eingefügt werden! Sie sind in Ihrem Ansatz korrekt, indem Sie ihn auf Anwendungsebene sicherstellen und validieren. So kann es gemacht werden.
Vielleicht möchten Sie auch diese http://www.mongodb.org/display/DOCS/Querying+and+nulls lesen
quelle