E11000 doppelter Schlüsselfehlerindex im Mongodb-Mungo

227

Es folgt mein userSchema im user.jsModell -

var userSchema = new mongoose.Schema({
    local: {
        name: { type: String },
        email : { type: String, require: true, unique: true },
        password: { type: String, require:true },
    },
    facebook: {
        id           : { type: String },
        token        : { type: String },
        email        : { type: String },
        name         : { type: String }
    }
});

var User = mongoose.model('User',userSchema);

module.exports = User;

So verwende ich es in meinem Controller -

var user = require('./../models/user.js');

So speichere ich es in der Datenbank -

user({'local.email' : req.body.email, 'local.password' : req.body.password}).save(function(err, result){
    if(err)
        res.send(err);
    else {
        console.log(result);
        req.session.user = result;
        res.send({"code":200,"message":"Record inserted successfully"});
    }
});

Fehler -

{"name":"MongoError","code":11000,"err":"insertDocument :: caused by :: 11000 E11000 duplicate key error index: mydb.users.$email_1  dup key: { : null }"} 

Ich habe die DB-Sammlung überprüft und es gibt keinen solchen doppelten Eintrag. Lassen Sie mich wissen, was ich falsch mache.

FYI - req.body.emailund req.body.passwordholen Werte.

Ich habe auch diesen Beitrag überprüft, aber keine Hilfe STACK LINK

Wenn ich es vollständig entfernt habe, wird das Dokument eingefügt, andernfalls wird der Fehler "Duplizieren" ausgegeben, selbst wenn ich einen Eintrag in der local.email habe

Trialcoder
quelle
1
Hatte den gleichen Fehler! Während der Entwicklung haben wir die automatische Indizierung deaktiviert und Schemanamen / -schlüssel in Kleinbuchstaben verwendet. Wir haben uns später für die Verwendung von TitleCase entschieden, konnten jedoch unsere Indexnamen nicht aktualisieren (dh titleCase anstelle von TitleCase). Als wir die Indizierung aktiviert haben, ist dieser Fehler aufgetreten. Es dauerte eine Weile, um es herauszufinden. Sie sollten sicherstellen, dass alle Namen / Schlüssel genau überall benannt sind.
Jeach
4
Ich hatte den gleichen Fehler und das Einstellen des Mungomodells unique: falsehatte keine Auswirkungen. Mir wurde klar, dass ich zuerst den Tisch fallen lassen musste und dann würde es funktionieren. Sie können wie etwas tun db.whateverthecollection.drop({}). Seien Sie vorsichtig, es löscht die Sammlung.
Pere
1
_id: mongoose.Types.ObjectId hinzufügen, da eine eindeutige ID erforderlich ist
Mayank Pandav

Antworten:

239

Die Fehlermeldung besagt, dass bereits ein Datensatz nullals E-Mail vorhanden ist. Mit anderen Worten, Sie haben bereits einen Benutzer ohne E-Mail-Adresse.

Die dazugehörige Dokumentation:

Wenn ein Dokument keinen Wert für das indizierte Feld in einem eindeutigen Index hat, speichert der Index einen Nullwert für dieses Dokument. Aufgrund der eindeutigen Einschränkung lässt MongoDB nur ein Dokument zu, dem das indizierte Feld fehlt. Wenn mehr als ein Dokument ohne Wert für das indizierte Feld vorhanden ist oder das indizierte Feld fehlt, schlägt die Indexerstellung mit einem doppelten Schlüsselfehler fehl.

Sie können die eindeutige Einschränkung mit dem Sparse-Index kombinieren, um diese Nullwerte aus dem eindeutigen Index zu filtern und den Fehler zu vermeiden.

eindeutige Indizes

Sparse-Indizes enthalten nur Einträge für Dokumente mit dem indizierten Feld, auch wenn das Indexfeld einen Nullwert enthält.

Mit anderen Worten, ein spärlicher Index ist in Ordnung, wenn mehrere Dokumente alle nullWerte haben.

spärliche Indizes


Aus Kommentaren:

Ihr Fehler besagt, dass der Schlüssel benannt ist mydb.users.$email_1, was mich vermuten lässt, dass Sie einen Index für beide users.emailund haben users.local.email(der erstere ist alt und wird derzeit nicht verwendet). Das Entfernen eines Feldes aus einem Mungo-Modell wirkt sich nicht auf die Datenbank aus. Überprüfen Sie, mydb.users.getIndexes()ob dies der Fall ist, und entfernen Sie den unerwünschten Index manuell mit mydb.users.dropIndex(<name>).

RickN
quelle
1
Ich habe gerade das Nulldokument entfernt und es hat funktioniert :) +1 ..thx für die Hilfe
Trialcoder
70
Ihr Fehler besagt, dass der Schlüssel benannt ist mydb.users.$email_1, was mich vermuten lässt, dass Sie einen Index für beide users.emailund haben users.local.email(der erstere ist alt und wird derzeit nicht verwendet). Das Entfernen eines Feldes aus einem Mungo-Modell wirkt sich nicht auf die Datenbank aus. Überprüfen Sie, mydb.users.getIndexes()ob dies der Fall ist, und entfernen Sie den unerwünschten Index manuell mit mydb.users.dropIndex(<name>).
RickN
17
Oder verwenden db.users.dropIndexes()Sie, wenn Sie mehrere
Indexänderungen
1
Dies war ein Problem für mich, als ich das Mungo-Plugin passport-local-mongoose verwendete, ohne einen Benutzernamen für neue Benutzer festzulegen.
Show
1
Es ist eine Sache oder Perspektive oder vielleicht sogar eine Meinung, @titoih - ist null oder das Fehlen eines Wertes ein Wert wie jeder andere oder ist es ein Sonderfall? "a @ bc" und "a @ bc" sind gleich, sind "nichts" und "nichts" auch gleich? Bei einem nicht spärlichen Index lautet die Antwort in MongoDB "Ja". Andere Datenbanken (wie MySQL) würden "nein" sagen.
RickN
63

Wenn Sie sich noch in Ihrer Entwicklungsumgebung befinden, würde ich die gesamte Datenbank löschen und mit Ihrem neuen Schema neu beginnen.

Über die Befehlszeile

 mongo
use dbName;
db.dropDatabase();
exit
Rick
quelle
46
Ich denke, diese Lösung ist sehr aggressiv, ich denke, es reicht mit, db.collection.dropIndexes()wie cs_stackX sagte
JorgeGarza
2
@ GeorgeGarza Ich hatte das gleiche Problem. Ich habe gerade die Sammlung fallen lassen und danach hat alles gut funktioniert.
Sandip Subedi
Ich habe die Sammlung versehentlich mit einer eindeutigen ID für zwei meiner Felder initialisiert. Später, als ich mehrere Dokumente mit derselben ID hinzufügen wollte, konnte ich es nicht tun, bis ich die Sammlung gelöscht und erneut darauf zugegriffen hatte.
Meir Snyder
1
Wenn Sie neu in Ihrer Entwicklung sind, ist dies eine gute Gelegenheit, zu experimentieren und herauszufinden, wie Sie dieses Problem lösen können ... anstatt auf dieses Problem zu
stoßen,
@JorgeGarzas Kommentar macht Sinn. Abgelegte Indizes werden beim Neustart des Servers von der Schemadatei erneut erstellt. Auch hat es funktioniert.
Retr0
26

Überprüfen Sie die Sammlungsindizes.

Ich hatte dieses Problem aufgrund veralteter Indizes in der Sammlung für Felder, die unter einem anderen neuen Pfad gespeichert werden sollten.

Mongoose fügt einen Index hinzu, wenn Sie das Feld als eindeutig angeben.

Jegor
quelle
21

Grundsätzlich bedeutet dieser Fehler, dass Sie einen eindeutigen Index für ein bestimmtes Feld hatten, z. B. "email_address". Mongodb erwartet daher für jedes Dokument in der Sammlung einen eindeutigen E-Mail-Adresswert.

Nehmen wir also an, früher in Ihrem Schema wurde der eindeutige Index nicht definiert, und dann haben Sie zwei Benutzer mit derselben E-Mail-Adresse oder ohne E-Mail-Adresse (Nullwert) angemeldet.

Später haben Sie gesehen, dass ein Fehler aufgetreten ist. Sie versuchen also, dies zu korrigieren, indem Sie dem Schema einen eindeutigen Index hinzufügen. Ihre Sammlung enthält jedoch bereits Duplikate. In der Fehlermeldung wird daher angegeben, dass Sie keinen Duplikatwert erneut einfügen können.

Sie haben im Wesentlichen drei Möglichkeiten:

  1. Löschen Sie die Sammlung

    db.users.drop();

  2. Suchen Sie das Dokument mit diesem Wert und löschen Sie es. Angenommen, der Wert war null. Sie können ihn löschen mit:

    db.users.remove({ email_address: null });

  3. Löschen Sie den eindeutigen Index:

    db.users.dropIndex(indexName)

Ich hoffe das hat geholfen :)

Daksh Miglani
quelle
18

Ich möchte die Antwort / Lösung darauf so erklären, wie ich es einem 5-Jährigen erkläre, damit jeder verstehen kann.

Ich habe eine App. Ich möchte, dass sich Leute mit ihrer E-Mail-Adresse, ihrem Passwort und ihrer Telefonnummer registrieren. In meiner MongoDB-Datenbank möchte ich Personen anhand ihrer Telefonnummer und E-Mail-Adresse eindeutig identifizieren. Dies bedeutet, dass sowohl die Telefonnummer als auch die E-Mail-Adresse für jede Person eindeutig sein müssen.

Es gibt jedoch ein Problem: Ich habe festgestellt, dass jeder eine Telefonnummer hat, aber nicht jeder eine E-Mail-Adresse.

Diejenigen, die keine E-Mail-Adresse haben, haben mir versprochen, dass sie nächste Woche eine E-Mail-Adresse haben werden. Aber ich möchte, dass sie trotzdem registriert werden - also fordere ich sie auf, ihre Telefonnummern zu registrieren, wenn sie das E-Mail-Eingabefeld leer lassen.

Sie tun es.

Meine Datenbank BRAUCHT ein eindeutiges E-Mail-Adressfeld - aber ich habe viele Leute mit 'null' als E-Mail-Adresse. Also gehe ich zu meinem Code und sage meinem Datenbankschema, dass leere / null E-Mail-Adressfelder zugelassen werden sollen, die ich später mit eindeutigen E-Mail-Adressen ausfüllen werde, wenn die Personen, die versprochen haben, ihre E-Mails nächste Woche zu ihren Profilen hinzuzufügen.

Jetzt ist es eine Win-Win-Situation für alle (außer für Sie; -]): Die Leute registrieren sich, ich bin froh, ihre Daten zu haben ... und meine Datenbank ist glücklich, weil sie gut genutzt wird ... aber was ist mit Ihnen? Ich muss Ihnen noch den Code geben, der das Schema erstellt hat.

Hier ist der Code: HINWEIS: Die Eigenschaft sparse in E-Mail weist meine Datenbank an, Nullwerte zuzulassen, die später mit eindeutigen Werten gefüllt werden.

var userSchema = new mongoose.Schema({
  local: {
    name: { type: String },
    email : { type: String, require: true, index:true, unique:true,sparse:true},
    password: { type: String, require:true },
  },
  facebook: {
    id           : { type: String },
    token        : { type: String },
    email        : { type: String },
    name         : { type: String }
  }
});

var User = mongoose.model('User',userSchema);

module.exports = User;

Ich hoffe ich habe es schön erklärt. Viel Spaß beim Codieren / Hacken von NodeJS!

Daggie Blanqx - Douglas Mwangi
quelle
Wenn Sie einen sparseIndex und eine uniqueValidierung wünschen und andere Felder haben, die nicht erforderlich sind , müssen Sie die partialFilterExpressionOption verwenden. Siehe diese Antwort stackoverflow.com/a/34600171/728287
Gianfranco P.
4

Melden Sie sich in diesem Fall bei Mongo an und suchen Sie den Index, den Sie nicht mehr verwenden (im Fall von OP 'email'). Wählen Sie dann Drop Index Geben Sie hier die Bildbeschreibung ein

Bumsoverboard
quelle
3

Dies ist meine relavante Erfahrung:

Im 'Benutzer'-Schema habe ich' Name 'als eindeutigen Schlüssel festgelegt und dann eine Ausführung ausgeführt, die meiner Meinung nach die Datenbankstruktur eingerichtet hat.

Dann habe ich den eindeutigen Schlüssel in "Benutzername" geändert und beim Speichern von Daten in der Datenbank den Wert "Name" nicht mehr übergeben. Daher kann der Mongodb den Wert 'name' des neuen Datensatzes automatisch auf null setzen, was ein doppelter Schlüssel ist. Ich habe versucht, den Schlüssel 'name' als nicht eindeutigen Schlüssel {name: {unique: false, type: String}}im Schema 'User' festzulegen, um die ursprüngliche Einstellung zu überschreiben. Es hat jedoch nicht funktioniert.

Endlich habe ich meine eigene Lösung gefunden:

Legen Sie einfach einen zufälligen Schlüsselwert fest, der beim Speichern Ihres Datensatzes wahrscheinlich nicht mit dem Schlüssel 'name' dupliziert wird. Die einfache mathematische Methode erstellt '' + Math.random() + Math.random() eine zufällige Zeichenfolge.

Kobe Luo
quelle
12
Ich denke nicht, dass dies eine gültige Lösung ist, Sie maskieren nur das Problem.
Rick
Hässlich aber pragmatisch
Anthony
3

Ich hatte das gleiche Problem. Versuchtes Debuggen auf verschiedene Arten konnte nicht herausfinden. Ich habe versucht, die Sammlung fallen zu lassen, und danach hat es gut funktioniert. Dies ist zwar keine gute Lösung, wenn Ihre Sammlung viele Dokumente enthält. Wenn Sie sich jedoch in einem frühen Entwicklungsstadium befinden, versuchen Sie, die Sammlung zu löschen.

db.users.drop();
Sandip Subedi
quelle
2

Dies liegt daran, dass es bereits eine Sammlung mit demselben Namen mit Konfiguration gibt. Entfernen Sie die Sammlung einfach über die Mongo-Shell von Ihrem Mongodb und versuchen Sie es erneut.

db.collectionName.remove ()

Führen Sie jetzt Ihre Anwendung aus, es sollte funktionieren

Ignatius Andrew
quelle
2

Ich hatte ein ähnliches Problem und stellte fest, dass Mongo standardmäßig nur ein Schema pro Sammlung unterstützt. Speichern Sie Ihr neues Schema entweder in einer anderen Sammlung oder löschen Sie die vorhandenen Dokumente mit dem inkompatiblen Schema in Ihrer aktuellen Sammlung. Oder finden Sie eine Möglichkeit, mehr als ein Schema pro Sammlung zu haben.

Embedded_Mugs
quelle
2

Ich habe mich auch diesem Problem gestellt und es gelöst. Dieser Fehler zeigt, dass hier bereits eine E-Mail vorhanden ist. Sie müssen diese Zeile also nur aus Ihrem Modell für das E-Mail-Attribut entfernen.

unique: true

Dies könnte möglich sein, auch wenn es nicht funktioniert. Sie müssen also nur die Sammlung aus Ihrer MongoDB löschen und Ihren Server neu starten.

Inamur Rahman
quelle
1

Ich habe das gleiche Problem, als ich die folgende Konfiguration in meiner config / models.js hatte

module.exports.models = {
  connection: 'mongodb',
  migrate: 'alter'
}

Das Ändern der Migration von "ändern" in "sicher" hat das Problem für mich behoben.

module.exports.models = {
  connection: 'mongodb',
  migrate: 'safe'
}
Jam Risser
quelle
1

Das gleiche Problem nach dem Entfernen von Eigenschaften aus einem Schema nach dem ersten Erstellen einiger Indizes beim Speichern. Das Entfernen der Eigenschaft aus dem Schema führt zu einem Nullwert für eine nicht vorhandene Eigenschaft, die noch einen Index hatte. Hier hilft es, den Index zu löschen oder mit einer neuen Sammlung von Grund auf neu zu beginnen.

Hinweis: Die Fehlermeldung führt Sie in diesem Fall. es hat einen Pfad, der nicht mehr existiert. In meinem Fall war der alte Pfad ... $ uuid_1 (dies ist ein Index!), aber der neue ist .... * priv.uuid_1

chhtm
quelle
1

Ich hatte das gleiche Problem, als ich versuchte, das mit Mangoose definierte Schema zu ändern. Ich denke, das Problem ist auf den Grund zurückzuführen, dass beim Erstellen einer Sammlung einige grundlegende Prozesse ausgeführt werden, z. B. die Beschreibung der Indizes, die dem Benutzer verborgen sind (zumindest in meinem Fall). Die beste Lösung, die ich gefunden habe, bestand darin, die gesamte Sammlung zu löschen und wieder von vorne beginnen.

Rahul P.
quelle
0

Ich hatte das gleiche Problem. Problem war, dass ich ein Feld aus dem Modell entfernt habe. Als ich db fallen ließ, wurde es behoben

user86168
quelle
0

Für zukünftige Entwickler empfehle ich, den Index in INDEX TAB mit Kompass zu löschen. Dieses Dokument löscht KEIN Dokument in Ihrer Sammlung. Verwalten von Indizes

Edgar Olivar
quelle
-3

Ändern Sie den Sammlungsnamen, falls er bereits in der Datenbank vorhanden ist. Es wird ein Fehler angezeigt. Und wenn Sie eine Eigenschaft als eindeutig angegeben haben, tritt der gleiche Fehler auf.

arul mb
quelle
-4

Hatte das gleiche Problem, das ich durch Entfernen des uniqueAttributs für die Eigenschaft behoben habe .

Finden Sie einfach eine andere Möglichkeit, um eindeutige Eigenschaftswerte für Ihr Schema zu überprüfen oder zu überprüfen.

davyCode
quelle
Sie sollten ein Beispiel für Ihre Lösung angeben.
Josh Adams
Das erste Löschen der Sammlung und / oder Löschen der gesamten Sammlung aus der Mongo-Datenbank funktionierte, war jedoch eine vorübergehende Lösung. Das Erstellen eines weiteren Datensatzes mit ähnlichen Werten, obwohl sie unterschiedliche IDs hatten, führte immer noch zu einem Fehler beim doppelten E11000-Schlüssel. Ich wollte doppelte Werte für diese Eigenschaft zulassen, also habe ich einfach das eindeutige Attribut entfernt.
davyCode
-7

Bitte löschen Sie die Sammlung oder löschen Sie die gesamte Sammlung aus der MongoDB-Datenbank und versuchen Sie es später erneut.

Vittal Kamkar
quelle