132 votes

L'index unique de Mongoose ne fonctionne pas !

J'essaie de permettre à MongoDB de détecter une valeur dupliquée en se basant sur son index. Je pense que c'est possible dans MongoDB, mais à travers le wrapper Mongoose, les choses semblent être cassées. Donc pour quelque chose comme ça :

User = new Schema ({
  email: {type: String, index: {unique: true, dropDups: true}}
})

Je peux enregistrer 2 utilisateurs avec le même email. Dommage.

La même question a été soulevée ici : https://github.com/LearnBoost/mongoose/issues/56 mais ce fil de discussion est vieux et ne mène à rien.

Pour l'instant, j'appelle manuellement la base de données pour trouver l'utilisateur. Cet appel n'est pas coûteux puisque "email" est indexé. Mais ce serait quand même bien de pouvoir le gérer nativement.

Quelqu'un a-t-il une solution à ce problème ?

136voto

esjd Points 1154

Oups ! Il suffit de redémarrer Mongo.

44voto

jpillora Points 1416

Oups ! Il suffit de redémarrer Mongo.

Et ré-indexer aussi, avec :

mongo <db-name>
> db.<collection-name>.reIndex()

En test, comme je n'ai pas de données importantes, vous pouvez aussi le faire :

mongo <db-name>
> db.dropDatabase()

36voto

Neil Strain Points 556

J'ai rencontré le même problème : J'ai ajouté la contrainte unique pour le email à notre UserSchema après avoir déjà ajouté des utilisateurs à la base de données, et j'étais toujours en mesure de sauvegarder des utilisateurs avec des emails en double. J'ai résolu ce problème en procédant comme suit :

1) Supprimer tous les documents de la collection des utilisateurs.

2) Depuis le shell Mongo, exécutez la commande : db.users.createIndex({email: 1}, {unique: true})

En ce qui concerne l'étape 1, notez que dans la documentation de Mongo :

MongoDB ne peut pas créer un index unique sur le(s) champ(s) d'index spécifié(s) si la collection contient déjà des données qui violeraient la contrainte d'unicité de l'index.

https://docs.mongodb.com/manual/core/index-unique/

22voto

solstice333 Points 1083

J'ai déjà fait quelque chose comme ça :

const mongoose = require('mongoose');
const Schema = mongoose.Schema;

const FooSchema = new Schema({
   name: { type: String, required: true, index: true, unique: true }
});

const Foo = mongoose.model('Foo', FooSchema);

Foo.createIndexes();

module.exports = Foo

J'ai ajouté le Foo.createIndexes() ligne b.c. J'obtenais l'avertissement de dépréciation suivant lors de l'exécution du code :

(node:21553) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.

Je ne sais pas si Foo.createIndexes() est asynchrone, mais AFAIK les choses semblent fonctionner correctement

15voto


Marche à suivre pour résoudre le problème :

1 . Ajouter unique: true aux attributs.

let schema = new mongoose.Schema(
    {
        name: {
            type: String,
            unique: true,
            required: [true, "name required."],
        }
    }
);

module.exports = mongoose.model("role", schema);

2 . Déposez la collection - par exemple role (dernière ligne)

  • Il s'agit d'une solution simple à mettre en œuvre si vous avez déjà des valeurs en double.
  • Vous pouvez également supprimer tous les enregistrements de la collection de manière à ce qu'il y ait des valeurs en double pour la colonne unique ( name ci-dessus)

3 . Redémarrez le serveur Node.js, qui utilise mongoose bibliothèque.


Pourquoi certaines des autres réponses ne sont-elles pas correctes ?

  • En autoIndex est fixée à true

    • pas nécessaire, par défaut c'est vrai
  • Redémarrer la base de données

    • pas nécessaire, il suffit de redémarrer le serveur Node.js

  • Suivre les 3 étapes ci-dessus in sequence
    • Si vous manquez quelque chose, faites-le deux fois

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X