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 cassées. Donc, pour quelque chose comme ça:
User = new Schema ({
email: {type: String, index: {unique: true, dropDups: true}}
})
Je peux sauver 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, j'appelle manuellement la base de données pour rechercher l'utilisateur. Cet appel n’est pas coûteux, car "email" est indexé. Mais il serait toujours agréable de le laisser être traité de manière native.
Est-ce que quelqu'un a une solution à cela?
Oops! Il suffit de redémarrer Mongo.
Oops! Il suffit de redémarrer Mongo.
Et ré-index aussi!
En test, je viens de faire un:
mongo <db-name>
> db.dropDatabase()
Cependant, si vous y avez des données importantes, il vous suffit probablement de:
mongo <db-name>
> db.<collection-name>.reIndex()
J'ai rencontré le même problème: j'ai ajouté la contrainte unique pour le champ email
à notre UserSchema
après avoir déjà ajouté des utilisateurs à la base de données, et j'étais toujours capable de sauvegarder des utilisateurs avec des emails en dupe. J'ai résolu ceci en procédant comme suit:
1) Supprimez tous les documents de la collection d'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, d'après les documents 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 unique pour l'index.
Ce problème 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 la manière suivante:
yourModel.on('index', function(err) {
if (err?) {
console.error err
}
);
Ok, j’ai pu résoudre ce problème à partir du mongoshell en ajoutant l’index sur le champ et en définissant la propriété unique:
db.<collectionName>.ensureIndex({fieldName: 1}, {unique: true});
Shell devrait répondre comme suit:
{
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
Maintenant, pour tester rapidement depuis le Mongoshell:
var doc = {fieldName: 'abc'};
db.<collectionName>.insert(doc)
Devrait donner: WriteResult ({"nInserted": 1})
Mais en répétant encore:
db.<collectionName>.insert(doc)
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]\" }"
}
})
Selon la documentation: https://docs.mongodb.com/v2.6/tutorial/modify-an-index/
Pour modifier un index existant, vous devez supprimer et recréer l'index.
NE PAS REDÉMARRER MONGO!
1 - déposer la collection
db.users.drop()
2 - réindexer la table
db.users.ensureIndex({email: 1, type: 1}, {unique: true})
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 b.c. Je recevais 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 suis pas sûr que Foo.createIndexes()
soit asynchrone, mais les données AFAIK semblent bien fonctionner
vérifie que autoIndex dans le schéma est true, il peut être défini sur false (valeur par défaut) lorsque vous utilisez les options mongoose.connect
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, alors supprimez la collection et créez un index:
db.<collection_name>.drop()
db.<collection_name>.createIndex({'field':1}, {unique: true})
Maintenant, redémarrez mongoDB.
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 champ username
, tapez ceci:
db.users.dropIndex('username_1');
Dernière réponse: il n'est pas du tout nécessaire de redémarrer mongodb, Si la collection a déjà les mêmes noms de noms, mangouste ne recréera pas à nouveau vos index, donc, supprimez d'abord les index existants de la collection, vous exécutez mangouste, il va créer un nouvel index, processus ci-dessus a résolu mon problème.
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 sur le courrier électronique pour cette collection d'utilisateurs si vous ne souhaitez pas supprimer la collection. En utilisant cette commande, vous pouvez créer un index sur un courrier électronique.
db.User.createIndex({email:1},{unique: true})
Ou vous pouvez simplement supprimer la collection et ajouter l'utilisateur à nouveau.
Pour déposer la collection, vous pouvez entrer ceci:
db.User.drop()
J'ai fait face au même problème pendant un certain temps et ai fait beaucoup de recherches et la solution pour moi était la fonction createIndexes()
.
Je souhaite que cela aide.
donc le code sera comme ça.
User = new Schema ({
email: {type: String, unique: true}
});
User.createIndexes();
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 ne fonctionnait du tout. J'ai trouvé le travail suivant autour de Robo 3T:
_id_
comme valeur par défaut. Maintenant, choisissez Ajouter un indexemail
pour le champ de courrier électronique, par exempleFournissez les 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.