Eindeutiger Index in MongoDB
- Eindeutiger Index in MongoDB
- Verhalten des eindeutigen Index in MongoDB
- Validieren Sie eindeutige E-Mails mit Mongoose
In diesem Tutorial erfahren Sie mehr über eindeutige Indizes, einschließlich was sie sind und wie sie in MongoDB erstellt werden. Außerdem wird kurz beschrieben, wie die E-Mail-Adresse eines Benutzers in MongoDB eindeutig wird.
Das Inhaltsverzeichnis dieses Artikels lautet wie folgt:
- Eindeutige Indizes in MongoDB
- Erstellen Sie einen eindeutigen Index in MongoDB
- Verhalten eindeutiger Indizes in MongoDB
- Validieren Sie eindeutige E-Mails mit Mongoose
Eindeutiger Index in MongoDB
Ein eindeutiger Index garantiert, dass die indizierten Felder keine doppelten Werte enthalten, wodurch sichergestellt wird, dass die indizierten Felder eindeutig sind. Während der Erstellung einer Sammlung erstellt MongoDB standardmäßig einen eindeutigen Index für die Spalte _id
.
Verwenden Sie den Befehl db.collection.createIndex()
, um einen eindeutigen Index zu generieren, wobei die Option unique
auf true
gesetzt ist.
db.collection.createIndex( <key and index type specification>, { unique: true } )
Eindeutiger Index für ein einzelnes Feld
Verwenden Sie das folgende Verfahren in mongosh
, um einen eindeutigen Index für das Feld user_id
der Sammlung members
zu erstellen.
db.members.createIndex( { "user_id": 1 }, { unique: true } )
Eindeutiger zusammengesetzter Index
Bei zusammengesetzten Indizes können Sie auch eine eindeutige Einschränkung festlegen. Beispielsweise erzwingt MongoDB die Eindeutigkeit beim Kombinieren von Indexschlüsselwerten, wenn Sie die Eindeutigkeitsbeschränkung für einen zusammengesetzten Index verwenden.
Verwenden Sie die folgende Operation in mongosh
, um einen eindeutigen Index für die Felder groupNumber
, lastname
und firstname
der Sammlung members
zu erstellen.
db.members.createIndex( { groupNumber: 2, lastname: 1, firstname: 1 }, { unique: true } )
Der Index stellt sicher, dass jede Kombination der Werte groupNumber
, lastname
und firstname
eindeutig ist.
Betrachten Sie die folgende Sammlung mit dem folgenden Dokument.
{ _id: 1, a: [ { loc: "A", qty: 5 }, { qty: 10 } ] }
Erstellen Sie einen eindeutigen zusammengesetzten Multikey-Index für a.loc
und a.qty
.
db.collection.createIndex( { "a.loc": 1, "a.qty": 1 }, { unique: true } )
Die folgenden Dokumente können in die Sammlung aufgenommen werden, da der Index die Eindeutigkeit für die Kombination der Werte a.loc
und a.qty
garantiert.
db.collection.insertMany( [
{ _id: 2, a: [ { loc: "A" }, { qty: 6 } ] },
{ _id: 3, a: [ { loc: "A", qty: 12 } ] }
] )
Verhalten des eindeutigen Index in MongoDB
Einschränkungen:
Wenn die Sammlung bereits Daten enthält, die gegen die Eindeutigkeitsanforderung des Index verstoßen würden, kann MongoDB keinen eindeutigen Index für die bereitgestellten Indexfelder erstellen. Bei einem Hash-Index können Sie keine Eindeutigkeitsbeschränkung definieren.
Verwenden Sie Replikatsätze und Sharded-Cluster, um einen eindeutigen Index zu erstellen
Die Verwendung eines fortlaufenden Vorgangs zum Erstellen eines eindeutigen Indexes für Replikatsätze und fragmentierte Cluster erfordert das Stoppen aller Schreibvorgänge in die Sammlung während des gesamten Verfahrens.
Verwenden Sie den fortlaufenden Vorgang nicht, wenn Sie während des Vorgangs nicht alle Schreibvorgänge in die Sammlung stoppen können. Erstellen Sie stattdessen einen einzigartigen Index für die Sammlung, indem Sie Folgendes ausgeben:
db.collection.createIndex()
auf dem primären für einen Replikatsatzdb.collection.createIndex()
aufmongos
für einen Sharded-Cluster
Unique Constraint über separate Dokumente hinweg
Die Eindeutigkeitsanforderung gilt für jedes Dokument in der Sammlung. Der eindeutige Index verhindert, dass der indizierte Schlüssel in verschiedenen Dokumenten denselben Wert hat.
Da die Einschränkung nur für separate Dokumente gilt, kann ein Dokument ein Array von Elementen enthalten, die zu sich wiederholenden Indexschlüsselwerten für einen eindeutigen Multikey-Index führen, solange die Indexschlüsselwerte für das Dokument nicht mit denen für ein anderes Dokument dupliziert werden. Der wiederholte Indexeintrag wird in diesem Szenario nur einmal in den Index eingetragen.
Zum Beispiel eine Sammlung, die die folgenden Dokumente enthält.
{ _id: 1, a: [ { loc: "A", qty: 6 }, { qty: 10 } ] }
{ _id: 2, a: [ { loc: "A" }, { qty: 7 } ] }
{ _id: 3, a: [ { loc: "A", qty: 12 } ] }
Erstellen Sie einen eindeutigen zusammengesetzten Multikey-Index für a.loc
und a.qty
.
db.collection.createIndex( { "a.loc": 1, "a.qty": 1 }, { unique: true } )
Wenn kein anderes Dokument in dieser Sammlung einen Indexschlüsselwert von {"a.loc": "B", "a.qty": null}
hat, ermöglicht der eindeutige Index, dass das folgende Dokument in die Sammlung eingefügt wird.
db.collection.insertOne( { _id: 4, a: [ { loc: "B" }, { loc: "B" } ] } )
Eindeutiger Index und fehlendes Feld
Wenn ein Dokument in einem eindeutigen Index keinen Wert für das indizierte Feld enthält, speichert der Index einen Nullwert für dieses Dokument. MongoDB lässt aufgrund der Eindeutigkeitsbeschränkung zu, dass nur bei einem Dokument die indizierte Spalte fehlt.
Die Indexerstellung schlägt mit einem doppelten Schlüsselfehler fehl, wenn es mehr als ein Dokument ohne Wert für das indizierte Feld gibt oder wenn das indizierte Feld fehlt.
Eine Sammlung hat zum Beispiel einen eindeutigen Index auf x
.
db.collection.createIndex( { "x": 13 }, { unique: true } )
Wenn die Sammlung nicht bereits ein Dokument enthält, dem das Feld x
fehlt, ermöglicht der eindeutige Index das Einfügen eines Dokuments ohne das Feld x
.
db.collection.insertOne( { y: 2 } )
Wenn die Sammlung jedoch bereits ein Dokument ohne Feld x
enthält, schlägt der eindeutige Index beim Einfügen eines Dokuments ohne Feld x
fehl.
db.collection.insertOne( { z: 2 } )
Die Operation kann das Dokument aufgrund eines Verstoßes gegen die Eindeutigkeitsbeschränkung für den Wert des Felds x
nicht einfügen.
WriteResult({
"nInserted" : 0,
"writeError" : {
"code" : 12000,
"errmsg" : "E12000 duplicate key error index: test.collection.$a.b_1 dup key: { : null }"
}
})
Eindeutiger Teilindex
Nur die Dokumente in einer Sammlung, die einem bestimmten Filterausdruck entsprechen, werden in Teilindizes indiziert. Wenn Sie also sowohl einen partialFilterExpression
als auch einen Unique-Constraint verwenden, gilt der Unique-Constraint nur für Dokumente, die mit dem Filterausdruck übereinstimmen.
Wenn die Dokumente die Filteranforderungen nicht erfüllen, verhindert ein Teilindex mit Eindeutigkeitsbeschränkung nicht das Einfügen von Dokumenten, die die Eindeutigkeitsbeschränkung nicht erfüllen.
Sharded Cluster und Unique Index
Bei einem Hash-Index können Sie keine Eindeutigkeitsbeschränkung definieren.
Nur die folgenden Indizes können in einer Ranged-Sharding-Sammlung eindeutig sein.
- Der Indexwert des Shard-Schlüssels.
- Ein zusammengesetzter Index mit einem Präfix als Shard-Schlüssel.
- Der Standardindex
_id
; Der_id
-Index erzwingt jedoch nur dann die Eindeutigkeitsanforderung pro Shard, wenn die_id
-Felder nicht der Shard-Schlüssel oder das Shard-Schlüssel-Präfix sind.
Die eindeutigen Indexeinschränkungen bedeuten Folgendes:
- Sie können die Sammlung nicht teilen, wenn die Sammlung andere eindeutige Indizes für eine zu teilende Sammlung hat.
- Sie können keine eindeutigen Indizes für eine bereits fragmentierte Sammlung für andere Felder erstellen.
Sparse- und Non-Sparse-Unique-Index
Ab MongoDB 5.0 kann eine einzelne Sammlung eindeutige Sparse- und Non-Sparse-Indizes mit demselben Schlüsselmuster haben.
Eindeutige und spärliche Indexerstellung
In diesem Beispiel werden mehrere Indizes mit demselben Schlüsselmuster und unterschiedlichen sparse
-Auswahlmöglichkeiten erstellt.
db.scores.createIndex( { score : 2 }, { name: "unique_index", unique: true } )
db.scores.createIndex( { score : 2 }, { name: "unique_sparse_index", unique: true, sparse: true } )
Grund- und Sparse-Index-Erstellung
Mit und ohne Option sparse
können Sie einfache Indizes mit demselben Schlüsselmuster aufbauen.
db.scores.createIndex( { score : 2 }, { name: "sparse_index", sparse: true } )
db.scores.createIndex( { score : 2 }, { name: "basic_index" } )
Doppelte Schlüsselmuster in Basis- und eindeutigen Indizes
Mit MongoDB 5.0 haben Sie möglicherweise grundlegende und eindeutige Indizes mit demselben Schlüsselmuster. Aufgrund der Duplizierung von Schlüsselmustern ist es möglich, bereits indizierten Feldern einen eindeutigen Index hinzuzufügen.
Beispiel:
Erstellen Sie einen Basisindex mit dem Schlüsselmuster { score: 2 }
und fügen Sie drei Dokumente ein.
db.scores.createIndex( { score : 1 }, { name: "basic_index" } )
db.scores.insert( { score : 1 } )
db.scores.insert( { score : 2 } )
db.scores.insert( { score : 4 } )
Erstellen Sie einen eindeutigen Index mit demselben Schlüsselmuster { score: 2 }
.
db.scores.createIndex( { score : 2 }, { name: "unique_index", unique: true } )
Der Versuch, ein doppeltes score
-Dokument einzufügen, schlägt aufgrund des eindeutigen Index fehl.
db.scores.insert( { score : 4 } )
Validieren Sie eindeutige E-Mails mit Mongoose
Mit Mongoose können Sie Duplikate in Ihren Datenbanken durch Validierung verhindern. Die Validierung ist im Typ Schema
definiert und ist eine Middleware.
Sie können Ihre Validierung auch im Schema erstellen oder die integrierte Validierung von Mongooses verwenden. Um Duplikate zu vermeiden, empfehlen wir die Verwendung der Eigenschaft unique
, da sie Mongoose mitteilt, dass jedes Dokument einen eindeutigen Wert für den angegebenen Pfad haben sollte.
Es ist eine Abkürzung für die Erstellung eines eindeutigen MongoDB-Index für, in diesem Fall, email
.
Wenn Sie darauf warten, dass der Index erstellt wird, können Sie Mongooses Promise-basiertes Ereignis Model.init()
verwenden, wie unten gezeigt.
const User = mongoose.model('User', mongoose.Schema({
email: {type: String, required: true, match: /.+\@.+\..+/, unique: true}
}));
await User.create([
{email: 'gmail@google.com'}, {email: 'bill@microsoft.com'},
{email: 'test@gmail.com'}
]);
await User.init();
try {
await User.create({email: 'gmail@google.com'});
} catch (error) {
error.message; // 'E12000 duplicate key error...'
}
In diesem Artikel werden eindeutige Indizes in MongoDB ausführlich besprochen. Darüber hinaus erfolgt die Validierung eindeutiger E-Mails am Ende in mongoose
von MongoDB.