2016-05-14 1 views
0

J'ai reconnu cette question a beenaskedbefore, mais aucune des solutions ne semblait fonctionner pour moi.Validation unique ne fonctionnant pas dans Mongoose

J'ai un modèle simple je définis comme ceci:

const mongoose = require('mongoose') 
const { Schema } = mongoose 

let subscriberSchema = new Schema({ 
    firstName: { type: String, required: true }, 
    email: { type: String, required: true, unique: true } 
}, { timestamps: true }) 

let Subscriber = mongoose.model('Subscriber', subscriberSchema) 

Si j'exécutez la commande suivante (dans le REPL, donc pas de problèmes async), je vous attendez à voir une erreur en cours d'enregistrement pour le deuxième appel à create.

Subscriber.create({ firstName: "Landon", email: "[email protected]" }) 
Subscriber.create({ firstName: "Landon", email: "[email protected]" }, function(err) { 
    console.log("ERROR", err) 
}) 

Au lieu de cela, je vois "ERROR" null.

Si j'exécute une requête count ou une requête find, je peux voir que les deux modèles ont été créés. Qu'est-ce que je fais mal?

Modifier

Voici quelques-unes des choses que je l'ai déjà essayé:

  • Redémarrez MongoDB après avoir ajouté l'index
  • Suppression de tous les enregistrements existants de sorte qu'il n'y a pas de dossiers existants qui pourrait violer la contrainte d'unicité
  • Définition de l'attribut email toutes ces façons (je l'ai vu différentes implémentations dans des endroits différents): { type: String, required: true, unique: true }, { type: String, required: true, index: true, unique: true }, { type: String, required: true, index: { unique: true } }.
+0

Pouvez-vous modifier votre question d'inclure ce que vous avez vérifié les questions liées afin que nous ne devons pas poser ces mêmes questions? – JohnnyHK

+0

@JohnnyHK Bien sûr, pas de problème. Actualisé. – LandonSchropp

Répondre

2

Ceci est une chose très compliquée à résoudre avec un nœud, comme vous le savez son asynchrone. Si vous exécutez les deux requêtes en parallèle, les deux vérifient si le document existe en même temps et les deux vont essayer de créer l'enregistrement.

Il y a deux choses que vous pourriez faire.

Créer un index unique

YourModel.index({ email: 1}, { unique: true }) 

OU
Utilisez Mise à jour avec $ setOnInsert

var pk = {email : 'your email'}; 
YourModel.update(pk, { 
     $setOnInsert : data 
    }, {upsert : true}) 

Et Assurez-vous que l'indice existe dans MongoDB.

Mongoose ne modifie pas l'index sur jeu de clés. Commencez par supprimer l'index du shell mongo.

db.collection.dropIndex({email : 1}) 

Le processus de redémarrage du noeud et de la fonction mongo va maintenant créer un index avec une contrainte unique.

+0

Je ne pense pas avoir été clair dans ma question. Les exemples d'appels 'Subscriber.create' étaient dans le REPL du noeud, donc il ne devrait pas y avoir de problèmes asynchrones. J'ai couru le premier créer, j'ai attendu que cela se termine, puis a couru le second. Si je lance des appels ultérieurs à 'create' plus tard, je vois toujours les mêmes problèmes. – LandonSchropp

+0

Chaque fois que vous ajoutez un index, vous devez redémarrer le processus de noeud, Mongoose autoIndex essayera d'assurer des index.vous pouvez le voir avec debug mongoose. Et assurez-vous que les index sont là dans la collection par * getIndexes() * – anwerj

+0

J'ai essayé de redémarrer le serveur ainsi que mongod, mais malheureusement, cela ne semble pas aider. Exécuter 'Scheduler.collection.getIndexes()' résout à ceci: '{_id_: [['_id', 1]], email_1: [['email', 1]]}'. Je ne vois rien à propos de l'unicité, mais je ne suis pas sûr si je devrais, et je ne sais pas comment y remédier. – LandonSchropp