Le week-end dernier, je passais au détour d'un groupe d'entraide entre développeurs débutants sur lequel j'échange régulièrement afin de donner quelques conseils, lorsque je suis tombé sur un utilisateur de Mongoose ayant le problème suivant :

Mon schéma ne contient pas d'index d'unicité, et pourtant lorsque j'essaye d'insérer une donnée, MongoDB me renvoie cette erreur: "E11000 duplicate key error collection: db.products index: name_1 dup key: {name: "XXX"}"

Avec en copie le schéma utilisé par Mongoose :

const productSchema = new mongoose.Schema({
  name: {type: String, required: true},
  image: {type: String, required: true}
});

Et surprise, il n'y a effectivement pas de d'index d'unicité sur le schéma, et ce dernier a même par la suite essayé de forcer la chose en spécifiant "unique: false" dans son attribut "name", ce qui ne changea rien.

Le problème

D'où vient ce problème ? Est-ce un bug de MongoDB ou de Mongoose ? La réponse est : aucun des deux.

C'est en fait ce qu'on pourrait appeler un effet de bord.

Lorsque l'on utilise Mongoose en lisant la doc en diagonale, on peut vite être amené à penser que ce dernier permet de gérer les index (notamment d'unicité) de manière automatisée grâce aux schémas.

Mais la vérité est que Mongoose ne gère que la création automatique des index, mais ne gère ni la modification, ni la suppression.

Ce qui signifie que si vous avez ajouté "required: true" à l'un des attributs de votre modèle et relancé votre programme, un index d'unicité aura été ajouté à votre collection dans votre base MongoDB.

Et même si vous avez supprimé cet index sur votre schéma et relancé votre programme, l'index sera toujours présent en base de donnée, impliquant donc une erreur de "clé dupliquée" sur votre attribut s'il existe déjà un document avec un attribut de même valeur.

C'est d'ailleurs souvent ce qui se passe lorsque l'on utilise un schéma que l'on trouvé sur internet et que l'on modifie ensuite.

La solution

Pour résoudre ce problème, il suffit d'utiliser votre client graphique (ou CLI) préféré pour vous connecter à votre base de données, choisissez la collection qui pose problème et listez les index de cette dernière.

Vous devriez tomber sur un index ayant le même nom que celui renvoyé dans l'erreur (ici l'index s'appelait name_1) et vous n'avez plus qu'à le supprimer.

Il ne vous restera plus qu'à réessayer de créer votre document et vous n'aurez plus d'erreur lié à la duplication de clé unique !

J'espère que cet article vous aura été utile, et à bientôt sur le blog !

À propos de l'auteur

Hello, je suis Nicolas Brondin-Bernard, ingénieur web indépendant depuis 2015 passionné par le partage de d'expériences et de connaissances.

Aujourd'hui je suis aussi coach pour développeurs web juniors, tu peux me contacter sur nicolas@brondin.com, sur mon site ou devenir membre de ma newsletter pour ne jamais louper le meilleur article de la semaine et être tenu au courant de mes projets !


Photo par Christopher Ott sur Unsplash