web-dev-qa-db-fra.com

E11000 index d'erreur de clé en double dans mongodb mangouste

Voici mon schéma user dans user.js modèle -

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;

Voici comment je l’utilise dans mon contrôleur -

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

C'est comme ça que je le garde dans la base de données -

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

Erreur -

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

J'ai vérifié la collection de base de données et aucune entrée en double de ce type n'existe, laissez-moi savoir ce que je fais mal?

FYI - req.body.email et req.body.password récupèrent des valeurs.

J'ai aussi vérifié ce post mais pas d'aide STACK LINK

Si j'ai supprimé complètement, le document est inséré, sinon l'erreur "Dupliquer" est générée, même si j'ai une entrée dans le fichier local.email.

185
Trialcoder

Le message d'erreur indique qu'il existe déjà un enregistrement avec null comme courrier électronique. En d'autres termes, vous avez déjà un utilisateur sans adresse e-mail.

La documentation pertinente pour cela:

Si un document n'a pas de valeur pour le champ indexé dans un index unique, l'index stockera une valeur null pour ce document. En raison de la contrainte unique, MongoDB n'autorisera qu'un seul document sans le champ indexé. S'il existe plus d'un document sans valeur pour le champ indexé ou s'il manque le champ indexé, la construction de l'index échouera avec une erreur de clé en double.

Vous pouvez combiner la contrainte unique avec l'index fragmenté pour filtrer ces valeurs null à partir de l'index unique et éviter l'erreur.

index uniques

Les index fragmentés ne contiennent que des entrées pour les documents comportant le champ indexé, même si le champ d'index contient une valeur null.

En d'autres termes, un index fragmenté est acceptable avec plusieurs documents ayant tous la valeur null.

index clairsemés


De commentaires:

Votre erreur indique que la clé s'appelle mydb.users.$email_1, ce qui me fait penser que vous avez un index sur users.email et users.local.email (l'ancien étant ancien et inutilisé pour le moment). La suppression d'un champ d'un modèle Mongoose n'affecte pas la base de données. Vérifiez avec mydb.users.getIndexes() si c'est le cas et supprimez manuellement l'index indésirable avec mydb.users.dropIndex(<name>).

189
RikkusRukkus

Si vous êtes toujours dans votre environnement de développement, je supprimerais toute la base de données et recommencerais avec votre nouveau schéma.

À partir de la ligne de commande

➜ mongo
use dbName;
db.dropDatabase();
exit
50
Rick

Vérifier les index de collection.

J'avais ce problème en raison d'index obsolètes dans la collection de champs, qui devraient être stockés par un nouveau chemin différent.

Mongoose ajoute un index lorsque vous indiquez que le champ est unique.

16
Yegor

Eh bien, fondamentalement, cette erreur indique que vous avez un index unique sur un champ particulier, par exemple "email_address". Par conséquent, mongodb attend une valeur d'adresse électronique unique pour chaque document de la collection.

Supposons donc que précédemment, dans votre schéma, l'index unique n'était pas défini, puis vous avez inscrit 2 utilisateurs avec la même adresse électronique ou sans adresse électronique (valeur null).

Plus tard, vous avez vu qu'il y avait une erreur. vous essayez donc de le corriger en ajoutant un index unique au schéma. Mais votre collection contient déjà des doublons. Le message d'erreur indique donc que vous ne pouvez plus insérer de doublons.

Vous avez essentiellement trois options:

  1. Déposer la collection

    db.users.drop();

  2. Recherchez le document qui a cette valeur et supprimez-le. Disons que la valeur était nulle, vous pouvez la supprimer en utilisant:

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

  3. Supprimer l'index Unique:

    db.users.dropIndex(indexName)

J'espère que cela a aidé :)

14
Daksh Miglani

Je veux expliquer la réponse/solution à ce problème, comme je l'explique à un enfant de 5 ans, afin que tout le monde puisse comprendre.

J'ai une application.Je veux que les gens s'enregistrent avec leur email, mot de passe et numéro de téléphone. Dans ma base de données MongoDB, je souhaite identifier les personnes en fonction de leurs numéros de téléphone et de leurs adresses électroniques. Cela signifie donc que le numéro de téléphone et l'adresse électronique doivent être uniques pour chaque personne.

Cependant, il y a un problème: j'ai réalisé que tout le monde a un numéro de téléphone mais pas tout le monde a une adresse e-mail.

Ceux qui n'ont pas d'adresse e-mail m'ont promis qu'ils en auraient une d'ici la semaine prochaine. Mais je veux quand même qu'ils soient enregistrés - je leur dis donc de continuer à enregistrer leurs numéros de téléphone car ils laissent le champ de saisie du courrier électronique vide.

Ils le font.

Ma base de données A BESOIN d'un champ d'adresse email unique - mais j'ai beaucoup de gens avec 'null' comme adresse email. Je vais donc dans mon code et dire à mon schéma de base de données d'autoriser les champs d'adresse e-mail vides/nuls que je remplirai plus tard d'adresses e-mail uniques lorsque les personnes ayant promis d'ajouter leurs e-mails à leurs profils la semaine prochaine.

Alors tout le monde est gagnant pour tout le monde (mais vous; -]): les gens s’enregistrent, je suis heureux d’avoir leurs données ... et ma base de données est heureuse car elle est bien utilisée ... mais vous? Je suis encore à vous donner le code qui a fait le schéma.

Voici le code: REMARQUE: la propriété sparse de l'email est ce qui indique à ma base de données d'autoriser les valeurs NULL qui seront ultérieurement renseignées avec des valeurs uniques.

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;

J'espère que je l'ai bien expliqué. Happy NodeJS codage/piratage!

11
Daggie Blanqx

J'ai fait face à des problèmes similaires, je viens d'effacer les index de domaines particuliers, puis cela fonctionne pour moi. https://docs.mongodb.com/v3.2/reference/method/db.collection.dropIndexes/

7
mad Man

Voici mon expérience la plus récente:

Dans le schéma 'User', j'ai défini le nom 'name' comme clé unique, puis j'ai exécuté une exécution qui, je pense, avait configuré la structure de la base de données.

Ensuite, j'ai changé la clé unique en tant que "nom d'utilisateur" et je n'ai plus transmis la valeur "nom" lorsque j'ai sauvegardé les données dans la base de données. Ainsi, mongodb peut automatiquement définir la valeur 'name' du nouvel enregistrement comme null, qui est une clé dupliquée. J'ai essayé la clé "nom" comme clé non unique {name: {unique: false, type: String}} dans le schéma "Utilisateur" afin de remplacer le paramètre d'origine. Cependant, cela n'a pas fonctionné.

Enfin, j'ai créé ma propre solution:

Il suffit de définir une valeur de clé aléatoire qui ne sera probablement pas dupliquée en tant que clé "nom" lorsque vous sauvegardez votre enregistrement de données. Méthode simplement mathématique '' + Math.random() + Math.random() crée une chaîne aléatoire.

4
Kobe Luo

J'ai eu le même problème. Essayé de déboguer différentes façons ne pouvaient pas comprendre. J'ai essayé de laisser tomber la collection et cela a bien fonctionné par la suite. Bien que ce ne soit pas une bonne solution si votre collection contient de nombreux documents. Mais si vous êtes au début de votre développement, essayez de laisser tomber la collection.

db.users.drop();
3
Sandip Subedi

J'ai eu un problème similaire et j'ai réalisé que par défaut mongo ne prend en charge qu'un seul schéma par collection. Stockez votre nouveau schéma dans une autre collection ou supprimez les documents existants contenant le schéma incompatible dans votre collection actuelle. Ou trouvez un moyen d'avoir plus d'un schéma par collection.

2
Embedded_Mugs

En effet, il existe déjà une collection du même nom avec configuration .. Supprimez simplement la collection de votre mongodb via mongo Shell et réessayez.

db.collectionName.remove ()

maintenant lancez votre application ça devrait marcher

2
Ignatius Andrew

J'ai eu le même problème lorsque j'ai essayé de modifier le schéma défini à l'aide de mangoose. Je pense que le problème est dû à la raison qu'il existe un processus sous-jacent lors de la création d'une collection, telle que la description des index cachés à l'utilisateur (du moins dans mon cas). La meilleure solution que j'ai trouvée était donc de supprimer l'ensemble de la collection. et recommencer.

1
Rahul P

J'ai eu le même problème quand j'avais la configuration suivante dans mes config/models.js

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

Changer de migrer de 'alter' à 'safe' l'a corrigé.

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

même problème après la suppression des propriétés d'un schéma after en construisant d'abord quelques index lors de la sauvegarde. la suppression de la propriété du schéma conduit à une valeur null pour une propriété non existante, qui avait toujours un index. déposer un index ou commencer avec une nouvelle collection à partir de zéro aide ici.

remarque: le message d'erreur vous mènera dans ce cas. il y a un chemin, ça n'existe plus. Dans mon cas, l'ancien chemin était ... $ uuid_1 (il s'agit d'un index!), mais le nouveau est .... * priv.uuid_1

1
chhtm

J'ai eu le même problème. Le problème était que j'ai supprimé un champ du modèle. Quand j'ai laissé tomber db ça corrige

1
user86168

J'ai également fait face à ce problème et je l'ai résolu. Cette erreur montre que le courrier électronique est déjà présent ici. Il vous suffit donc de supprimer cette ligne de votre attribut Model for email.

unique: true

Cela pourrait être possible même si cela ne fonctionnera pas. Il suffit donc de supprimer la collection de votre MongoDB et de redémarrer votre serveur.

1
Inamur Rahman