Indice di errore chiave duplicato E11000 in mangusta mongodb


229

Di seguito è riportato il mio userschema nel user.jsmodello -

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;

Ecco come lo sto usando nel mio controller -

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

Ecco come lo sto salvando nel db -

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"});
    }
});

Errore -

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

Ho controllato la raccolta di db e non esiste una voce così duplicata, fammi sapere cosa sto facendo di sbagliato?

Cordiali saluti - req.body.emaile req.body.passwordstanno recuperando valori.

Ho anche controllato questo post ma nessun aiuto STACK LINK

Se l'ho rimosso completamente, inserisce il documento, altrimenti genera l'errore "Duplica" anche se ho una voce in local.email


1
Ha avuto lo stesso errore! Durante lo sviluppo abbiamo disabilitato l'indicizzazione automatica e abbiamo utilizzato nomi / chiavi dello schema in minuscolo. Successivamente abbiamo deciso di utilizzare TitleCase, ma non siamo riusciti ad aggiornare i nomi dei nostri indici (ad esempio: titleCase invece di TitleCase). Quindi quando abbiamo abilitato l'indicizzazione, abbiamo riscontrato questo errore. Ci è voluto un po 'di tempo per capirlo. Ti consigliamo di assicurarti che tutti i nomi / le chiavi siano nominati esattamente ovunque.
Jeach,

6
Ho avuto lo stesso errore e l'impostazione del modello di mangusta unique: falsenon ha avuto alcun impatto. Mi sono reso conto che prima dovevo abbandonare il tavolo e poi avrebbe funzionato. Puoi fare qualcosa come db.whateverthecollection.drop({}). Fai attenzione, elimina la raccolta.
Pere

1
_id: mongoose.Types.ObjectId aggiunto perché è richiesto un ID univoco
Mayank Pandav

Risposte:


241

Il messaggio di errore dice che c'è già un record con nullcome e-mail. In altre parole, hai già un utente senza un indirizzo email.

La documentazione pertinente per questo:

Se un documento non ha un valore per il campo indicizzato in un indice univoco, l'indice memorizzerà un valore null per questo documento. A causa del vincolo univoco, MongoDB consentirà solo un documento privo del campo indicizzato. Se è presente più di un documento senza un valore per il campo indicizzato o manca il campo indicizzato, la generazione dell'indice avrà esito negativo con un errore chiave duplicato.

È possibile combinare il vincolo univoco con l'indice sparse per filtrare questi valori null dall'indice univoco ed evitare l'errore.

indici univoci

Gli indici sparsi contengono solo voci per i documenti che hanno il campo indicizzato, anche se il campo dell'indice contiene un valore nullo.

In altre parole, un indice sparso va bene con più documenti tutti con nullvalori.

indici sparsi


Dai commenti:

Il tuo errore dice che il nome della chiave mydb.users.$email_1mi fa sospettare che tu abbia un indice su entrambi users.emaile users.local.email(il primo è vecchio e inutilizzato al momento). La rimozione di un campo da un modello Mongoose non influisce sul database. Verificare mydb.users.getIndexes()se questo è il caso e rimuovere manualmente l'indice indesiderato con mydb.users.dropIndex(<name>).


1
Ho appena rimosso quel documento null e ha funzionato :) +1 ..thx per l'aiuto
Trialcoder

70
Il tuo errore dice che il nome della chiave mydb.users.$email_1mi fa sospettare che tu abbia un indice su entrambi users.emaile users.local.email(il primo è vecchio e inutilizzato al momento). La rimozione di un campo da un modello Mongoose non influisce sul database. Verificare mydb.users.getIndexes()se questo è il caso e rimuovere manualmente l'indice indesiderato con mydb.users.dropIndex(<name>).
RickN,

17
Oppure utilizza db.users.dropIndexes()se stai apportando più modifiche all'indice
cs_stackX

1
Questo è stato un problema per me quando stavo usando il plugin mongoose passport-local-mongoose senza impostare un nome utente per i nuovi utenti.
mostra il

1
È una questione o una prospettiva o forse anche un'opinione, @titoih - è nullo o l'assenza di un valore un valore come un altro o è un caso speciale? "a @ bc" e "a @ bc" sono uguali, "niente" e "niente" sono uguali? Con un indice non sparse la risposta è "sì" in MongoDB. Altri database (come MySQL) direbbero "no".
RickN,

65

Se sei ancora nel tuo ambiente di sviluppo, lascerei cadere l'intero db e ricomincerei con il tuo nuovo schema.

Dalla riga di comando

 mongo
use dbName;
db.dropDatabase();
exit

47
Penso che questa soluzione sia molto aggressiva, penso sia abbastanza con db.collection.dropIndexes()come ha detto
cs_stackX

2
@JorgeGarza Ho avuto lo stesso problema. Ho appena lasciato cadere la collezione e tutto ha iniziato a funzionare bene dopo.
Sandip Subedi,

Ho accidentalmente inizializzato la raccolta con un ID univoco per due dei miei campi. In seguito, quando volevo aggiungere più documenti con lo stesso ID, non mi avrebbe permesso fino a quando non avessi eliminato la raccolta e riapprovata.
Meir Snyder,

1
Se sei nuovo nel tuo sviluppo, questa è una buona occasione per sperimentare e capire come risolverlo ... piuttosto che imbatterti in questo problema una volta che hai già archiviato gigabyte di dati utente
Janac Meena,

Il commento di @JorgeGarza ha un senso. Gli indici rilasciati verranno nuovamente ricostruiti dal file Schema al riavvio del server. Inoltre, ha funzionato.
Retr0

26

Controlla gli indici di raccolta.

Ho avuto questo problema a causa di indici obsoleti nella raccolta per i campi, che dovrebbero essere memorizzati da un nuovo percorso diverso.

Mongoose aggiunge indice, quando si specifica un campo come univoco.


22

Bene, in pratica questo errore dice che hai un indice univoco su un campo particolare, ad esempio: "indirizzo_email", quindi mongodb si aspetta un valore univoco dell'indirizzo email per ciascun documento della raccolta.

Diciamo, prima nel tuo schema l'indice univoco non era stato definito, e poi hai registrato 2 utenti con lo stesso indirizzo e-mail o senza indirizzo e-mail (valore null).

Più tardi, hai visto che c'era un errore. quindi provi a correggerlo aggiungendo un indice univoco allo schema. Ma la tua raccolta ha già duplicati, quindi il messaggio di errore dice che non puoi inserire nuovamente un valore duplicato.

Hai essenzialmente tre opzioni:

  1. Rilascia la raccolta

    db.users.drop();

  2. Trova il documento che ha quel valore ed eliminalo. Diciamo che il valore era null, puoi eliminarlo usando:

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

  3. Elimina l'indice univoco:

    db.users.dropIndex(indexName)

Spero che questo abbia aiutato :)


20

Voglio spiegare la risposta / soluzione a questo come sto spiegando a un bambino di 5 anni, in modo che tutti possano capire.

Ho un'app. Voglio che le persone si registrino con la loro e-mail, password e numero di telefono. Nel mio database MongoDB, voglio identificare le persone in modo univoco in base sia ai loro numeri di telefono che alle e-mail, quindi ciò significa che sia il numero di telefono che l'e-mail devono essere univoci per ogni persona.

Tuttavia, c'è un problema: mi sono reso conto che ognuno ha un numero di telefono ma non tutti hanno un indirizzo e-mail.

Coloro che non hanno un indirizzo e-mail mi hanno promesso che avranno un indirizzo e-mail entro la prossima settimana. Ma li voglio comunque registrati - quindi dico loro di procedere registrando i loro numeri di telefono mentre lasciano vuoto il campo di immissione dell'email.

Lo fanno.

Il mio database HA BISOGNO di un campo univoco di indirizzo e-mail, ma ho molte persone con "null" come indirizzo e-mail. Quindi vado al mio codice e dico al mio schema di database di consentire campi di indirizzi e-mail vuoti / nulli che in seguito riempirò con indirizzi univoci e-mail quando le persone che hanno promesso di aggiungere le loro e-mail ai loro profili la prossima settimana.

Quindi ora è un vantaggio per tutti (tranne te; -]): le persone si registrano, sono felice di avere i loro dati ... e il mio database è felice perché viene usato bene ... ma tu? Devo ancora darti il ​​codice che ha creato lo schema.

Ecco il codice: NOTA: la proprietà sparsa nell'email, è ciò che dice al mio database di consentire valori null che verranno successivamente riempiti con valori univoci.

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;

Spero di averlo spiegato bene. Happy NodeJS codifica / hacking!


se si desidera un sparseindice e una uniqueconvalida e si dispone di altri campi non richiesti, è necessario utilizzare l' partialFilterExpressionopzione Visualizza questa risposta stackoverflow.com/a/34600171/728287
Gianfranco P.


4

In questa situazione, accedi a Mongo per trovare l'indice che non stai più utilizzando (nel caso di "email" di OP). Quindi selezionare Elimina indice inserisci qui la descrizione dell'immagine


3

Questa è la mia esperienza importante:

Nello schema "Utente", ho impostato "nome" come chiave univoca e quindi ho eseguito alcune esecuzioni, che credo abbiano impostato la struttura del database.

Quindi ho cambiato la chiave univoca come "nome utente" e non ho più passato il valore "nome" quando ho salvato i dati nel database. Quindi il mongodb può impostare automaticamente il valore 'name' del nuovo record come null che è chiave duplicata. Ho provato la chiave "nome" impostata come chiave non univoca {name: {unique: false, type: String}}nello schema "Utente" per sostituire l'impostazione originale. Tuttavia, non ha funzionato.

Alla fine, ho creato la mia soluzione:

Basta impostare un valore chiave casuale che non sarà probabilmente duplicato nella chiave "name" quando si salva il record di dati. Semplicemente il metodo matematico '' + Math.random() + Math.random() crea una stringa casuale.


12
Non penso che questa sia una soluzione valida, stai solo mascherando il problema.
Rick,

Brutto ma pragmatico
Anthony,

3

Ho avuto lo stesso problema. Tentativi di debug in diversi modi non sono riusciti a capire. Ho provato a lasciare la collezione e dopo ha funzionato bene. Anche se questa non è una buona soluzione se la tua raccolta ha molti documenti. Ma se sei in uno stato iniziale di sviluppo, prova a eliminare la raccolta.

db.users.drop();

2

Questo perché esiste già una raccolta con lo stesso nome con la configurazione. Basta rimuovere la raccolta dal mongodb tramite la shell di mongo e riprovare.

db.collectionName.remove ()

ora esegui l'applicazione, dovrebbe funzionare


2

Ho avuto un problema simile e mi sono reso conto che per impostazione predefinita mongo supporta solo uno schema per raccolta. Archivia il tuo nuovo schema in una raccolta diversa o elimina i documenti esistenti con lo schema incompatibile all'interno della raccolta corrente. Oppure trova un modo per avere più di uno schema per raccolta.


2

Ho anche affrontato questo problema e l'ho risolto. Questo errore mostra che l'email è già presente qui. Quindi devi solo rimuovere questa riga dal tuo modello per l'attributo email.

unique: true

Questo potrebbe essere possibile anche se non funzionerà. Quindi è sufficiente eliminare la raccolta da MongoDB e riavviare il server.


1

Ho avuto questo stesso problema quando avevo la seguente configurazione nel mio config / models.js

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

La modifica della migrazione da "alter" a "safe" l'ha risolto per me.

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

1

stesso problema dopo aver rimosso le proprietà da uno schema dopo aver creato alcuni indici sul salvataggio. la rimozione della proprietà dallo schema porta a un valore nullo per una proprietà inesistente, che aveva ancora un indice. cadere indice o iniziare con una nuova collezione da zero aiuta qui.

nota: il messaggio di errore ti porterà in quel caso. ha un percorso, che non esiste più. nel mio caso il vecchio percorso era ... $ uuid_1 (questo è un indice!), ma quello nuovo è .... * priv.uuid_1


1

Ho avuto lo stesso problema quando ho provato a modificare lo schema definito usando mangoose. Penso che il problema sia dovuto al fatto che ci sono alcuni processi sottostanti eseguiti durante la creazione di una raccolta come la descrizione degli indici che sono nascosti all'utente (almeno nel mio caso). Quindi la migliore soluzione che ho trovato è stata quella di eliminare l'intera raccolta e ricominciare.


0

Ho avuto lo stesso problema. Il problema era che ho rimosso un campo dal modello. Quando ho lasciato cadere il db si risolve


0

per i futuri sviluppatori, consiglio di eliminare l'indice nella TABELLA INDICE usando la bussola ... questo NON ELIMINA QUALSIASI documento nella tua raccolta Gestisci gli indici


-3

Modificare il nome della raccolta se esiste già nel database, mostrerà un errore. E se hai dato una proprietà come unica si verificherà lo stesso errore.


-4

Ho avuto lo stesso problema l'ho risolto rimuovendo l' uniqueattributo sulla proprietà.

Basta trovare un altro modo per convalidare o verificare valori di proprietà univoci per lo schema.


Dovresti fornire un esempio con la tua soluzione.
Josh Adams,

Prima cancellando la raccolta e / o eliminando l'intera raccolta dal database mongo ha funzionato, è stata comunque una soluzione temporanea. La creazione di un altro record con valori simili, anche se avevano ID diversi, continuava a generare un errore di chiave duplicata E11000. Volevo consentire valori duplicati per quella proprietà, quindi ho semplicemente rimosso l'attributo univoco.
davyCode

-7

Cancella la raccolta o Elimina l'intera raccolta dal database MongoDB e riprova più tardi.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.