J'essaie de laisser MongoDB détecter une valeur en double en fonction de son index. Je pense que cela 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. Zut.
Le même problème a été exprimé ici: https://github.com/LearnBoost/mongoose/issues/56 , mais ce fil est ancien et ne mène à nulle part.
Pour l'instant, je passe manuellement un appel à la base de données pour trouver l'utilisateur. Cet appel n'est pas cher puisque «l'email» est indexé. Mais ce serait toujours bien de le laisser géré de manière native.
Quelqu'un at-il une solution à cela?
Réponses:
Oups! Il vous suffit de redémarrer mongo.
la source
Et ré-indexez aussi, avec:
Lors des tests, comme je n'ai pas de données importantes, vous pouvez également faire:
la source
J'ai rencontré le même problème: j'ai ajouté la contrainte unique pour le
email
champ à notreUserSchema
après avoir déjà ajouté des utilisateurs à la base de données, et j'étais toujours en mesure d'enregistrer des utilisateurs avec des e-mails dupliqués. J'ai résolu ce problème en procédant comme suit:1) Supprimez 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:
https://docs.mongodb.com/manual/core/index-unique/
la source
Ce comportement se produit également si vous avez laissé des doublons dans Mongo. Mongoose essaiera de les créer dans Mongo au démarrage de votre application.
Pour éviter cela, vous pouvez gérer cette erreur de cette façon:
yourModel.on('index', function(err) { if (err?) { console.error err } );
la source
Ok, j'ai pu résoudre cela à partir du mongoshell en ajoutant l'index sur le terrain et en définissant la propriété unique:
db.<collectionName>.ensureIndex({fieldName: 1}, {unique: true});
Shell devrait répondre de cette manière:
{ "createdCollectionAutomatically" : false, "numIndexesBefore" : 1, "numIndexesAfter" : 2, "ok" : 1 }
Maintenant, pour tester rapidement depuis le mongoshell:
var doc = {fieldName: 'abc'}; db.<collectionName>.insert(doc)
Doit donner: WriteResult ({"nInserted": 1})
Mais en répétant à nouveau:
Va donner:
WriteResult({ "nInserted" : 0, "writeError" : { "code" : 11000, "errmsg" : "insertDocument :: caused by :: 11000 E11000 duplicate key error index: fuelConsumption.users.$email_1 dup key: { : \"[email protected]\" }" } })
la source
J'ai 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é la
Foo.createIndexes()
ligne bc J'obtenais l'avertissement d'obsolescence suivant lorsque le code était en cours d'exécution:(node:21553) DeprecationWarning: collection.ensureIndex is deprecated. Use createIndexes instead.
Je ne sais pas si
Foo.createIndexes()
c'est asynchrone, mais les choses AFAIK semblent bien fonctionnerla source
index: true
création de mon index unique.Selon la documentation: https://docs.mongodb.com/v2.6/tutorial/modify-an-index/
NE REDÉMARREZ PAS MONGO!
1 - Déposez la collection
2 - réindexer le tableau
db.users.ensureIndex({email: 1, type: 1}, {unique: true})
la source
Mongoose est un peu lâche lors de l'application d'index uniques au niveau de l'application; par conséquent, il est préférable d'appliquer vos index uniques à partir de la base de données elle-même à l'aide de mongo cli ou de dire explicitement à mongoose que vous êtes sérieux au sujet de l'
unique
index en écrivant la ligne de code suivante juste après votre UserSchema:UserSchema.index({ username: 1, email: 1 }, { unique: true});
Cela appliquera l'index unique sur les champs
username
etemail
dans votre UserSchema. À votre santé.la source
Mongoose échouera silencieusement à ajouter un index unique lorsque:
Dans le premier cas, répertoriez les index avec
db.collection.getIndexes()
et supprimez l'ancien index avecdb.collection.dropIndex("index_name")
. Lorsque vous redémarrez l'application Mongoose, elle doit ajouter correctement le nouvel index.Dans le second cas, vous devez supprimer les doublons avant de redémarrer l'application Mongoose.
la source
mongoose-unique-validator
Comment utiliser ce plugin:
1) npm install --save mongoose-unique-validator
2) dans votre schéma, suivez ce guide:
// declare this at the top var mongoose = require('mongoose'); var uniqueValidator = require('mongoose-unique-validator'); // exampleSchema = mongoose.Schema({}) etc... exampleSchema.plugin(uniqueValidator); // module.exports = mongoose.model(...) etc....
3) méthodes de mangouste
Lorsque vous utilisez des méthodes comme
findOneAndUpdate
vous devrez passer cet objet de configuration:{ runValidators: true, context: 'query' }
ie. User.findOneAndUpdate( { email: '[email protected]' }, { email: '[email protected]' }, { runValidators: true, context: 'query' }, function(err) { // ... }
4) options supplémentaires
insensible à la casse
utilisez l'option uniqueCaseInsensitive dans votre schéma
ie. email: { type: String, index: true, unique: true, required: true, uniqueCaseInsensitive: true }
messages d'erreur personnalisés
ie. exampleSchema.plugin(uniqueValidator, { message: 'Error, expected {PATH} to be unique.' });
Vous pouvez maintenant ajouter / supprimer la propriété unique à vos schémas sans vous soucier du redémarrage de mongo, de la suppression de bases de données ou de la création d'index.
Mises en garde (tirées de la documentation):
Étant donné que nous nous appuyons sur des opérations asynchrones pour vérifier si un document existe dans la base de données, il est possible que deux requêtes s'exécutent en même temps, toutes les deux récupèrent 0, puis les deux s'insèrent dans MongoDB.
En dehors du verrouillage automatique de la collection ou du forçage d'une seule connexion, il n'y a pas de vraie solution.
Pour la plupart de nos utilisateurs, ce ne sera pas un problème, mais c'est un cas extrême dont il faut être conscient.
la source
Réponse la plus récente: il n'est pas du tout nécessaire de redémarrer mongodb, si colleciton a déjà des index de même nom, mongoose ne recréera pas vos index à nouveau, alors supprimez d'abord les index existants de colleciton, et maintenant, lorsque vous exécutez mangouste, il créera un nouvel index , le processus ci-dessus a résolu mon problème.
la source
Vous pouvez également résoudre ce problème en supprimant l'index;
supposons que vous souhaitiez supprimer l'index unique de la collection
users
et du champusername
, tapez ceci:db.users.dropIndex('username_1');
la source
Si la table / collection est vide, créez un index unique pour le champ:
db.<collection_name>.createIndex({'field':1}, {unique: true})
Si la table / collection n'est pas vide, supprimez la collection et créez un index:
db.<collection_name>.drop() db.<collection_name>.createIndex({'field':1}, {unique: true})
Maintenant, redémarrez mongoDB.
la source
vérifiez que autoIndex dans le schéma est true, il peut être défini sur false (true par défaut) lorsque vous utilisez les options mongoose.connect
la source
J'ai été confronté au même problème pendant un certain temps et j'ai fait beaucoup de recherches et la solution pour moi était la
createIndexes()
fonction.Je souhaite que cela aide.
donc le code sera comme ça.
User = new Schema ({ email: {type: String, unique: true} }); User.createIndexes();
la source
Si vous utilisez l'option
autoIndex: false
dans la méthode de connexion comme ceci:mongoose.connect(CONNECTION_STRING, { autoIndex: false });
Essayez de supprimer cela. Si cela ne fonctionne pas, essayez de redémarrer mongodb autant que suggéré dans ce fil.
la source
Vous pouvez définir votre schéma comme
User = new Schema ({ email: { type: String, unique: true } })
Mais peut-être que cela ne fonctionnera pas quand il y a déjà un document et après cela, vous avez changé le schéma de l'utilisateur. Vous pouvez créer un index par e-mail pour cette collection User si vous ne souhaitez pas supprimer la collection. En utilisant cette commande, vous pouvez créer un index sur l'e-mail.
db.User.createIndex({email:1},{unique: true})
Ou vous pouvez simplement supprimer la collection et ajouter à nouveau l'utilisateur.
Pour supprimer la collection, vous pouvez saisir ceci:
la source
Lorsque j'ai rencontré ce problème, j'ai essayé de supprimer la base de données, de redémarrer le serveur (nodemon) plusieurs fois et aucune des astuces n'a fonctionné du tout. J'ai trouvé le travail suivant, via Robo 3T:
_id_
par défaut. Maintenant, choisissez Ajouter un indexemail
pour le champ e-mail, par exempleFournissez des clés au format JSON. Par exemple
{ "email": 1 }
Cliquez sur la case à cocher Unique
Cela garantira qu'aucun e-mail en double n'est enregistré dans MongoDB.
la source
Assurez-vous que votre collection n'a pas de redondance du champ sur lequel vous venez de mettre l'index unique.
Ensuite, redémarrez simplement votre application (mangouste). Il suffit d'ajouter un index en silence.
la source
Suppression de tous les documents de la collection:
Et un redémarrage, comme d'autres l'ont mentionné, a fonctionné pour moi
la source
Si votre MongoDB fonctionne en tant que service (un moyen simple de le trouver est si vous n'avez pas besoin de vous connecter à la base de données sans démarrer le fichier mongod.exe via un terminal), après avoir effectué les modifications, vous devrez peut-être redémarrer le service et / ou supprimez complètement votre base de données.
C'est assez étrange car pour certains utilisateurs, le simple fait de déposer une seule collection fonctionnait. Certains d'entre eux avaient juste besoin de supprimer la base de données. Mais cela n'a pas fonctionné pour moi. J'ai abandonné la base de données, puis redémarré le service MongoDB Server.
Pour redémarrer un service de recherche Services sur la barre de recherche Windows puis trouver le service MongoDB, double-cliquez pour ouvrir puis arrêter et redémarrer le service.
Si les autres méthodes n'ont pas fonctionné pour vous, je pense que cela fera l'affaire.
la source
Dans mon cas, la mangouste était dépassée. Je l'ai vérifié en exécutant npm obsolète sur CMD. et mis à jour «mangouste».
Veuillez dire si cela a fonctionné pour vous aussi.
la source
Lorsque vous connectez votre base de données à l'application ajoutez cette option: "audoIndex: true" par exemple dans mon code j'ai fait ceci:
const options = { // your options go here ... // this code is the solution audoIndex: true } mongoose.connect(DB_URI, options);
J'ai également abandonné la collection avec laquelle j'ai un problème et je l'ai recréée pour m'assurer qu'elle fonctionnera. J'ai trouvé cette solution sur: https://dev.to/emmysteven/solved-mongoose-unique-index-not-working-45d5 J'ai aussi essayé des solutions comme "redémarrer MongoDB" mais cela n'a pas fonctionné pour moi.
la source