2012-11-27 37 views
15

Ich verwende dieses Schema mit mongoose 3.0.3 von npm:Mongoose einzigartige Validierung Fehlertyp

var schema = new Schema({ 

    _id: Schema.ObjectId, 
    email: {type: String, required: true, unique: true} 

}); 

Wenn ich versuche, eine E-Mail zu speichern, die bereits in db ist, erwarte ich ein ValidationError wie wenn ein required Feld bekommen wurde weggelassen. Dies ist jedoch nicht der Fall, ich bekomme eine MongoError: E11000 duplicate key error index.

Welche kein Validierungsfehler ist (geschieht, selbst wenn ich die einzigartige entfernen: true).

Irgendeine Idee warum?

+2

Randbemerkung: 'neueste npm mongoose' könnte in der Woche/Monat/Jahr bedeutungslos. Setzen Sie die Version, die Sie verwenden. – freakish

+2

Es tat es auch nach dem Entfernen von unique: true, weil, wie alexjamesbrown sagte, diese Spezifikation einen Index auf Ihrer DB erstellt. Dieser DB und dieser Index bleiben bestehen, bis Sie den Index oder den DB löschen. Das hast du wahrscheinlich schon verstanden, aber ich dachte mir, dass es jemanden helfen könnte, das herauszurufen. – juanpaco

Antwort

21

ich es bevorzuge ich setzen n Pfadüberprüfungsmechanismen, wie

UserSchema.path('email').validate(function(value, done) { 
    this.model('User').count({ email: value }, function(err, count) { 
     if (err) { 
      return done(err); 
     } 
     // If `count` is greater than zero, "invalidate" 
     done(!count); 
    }); 
}, 'Email already exists'); 

Dann wird es nur in ValidationError gewickelt bekommen und wird als erstes Argument zurück, wenn Sie validate oder save nennen.

+0

Das ist die richtige Antwort. Es sollte ein benutzerdefinierter Validator für den Pfad sein, keine Pre-save-Funktion. – user3344977

+1

Dies funktioniert, aber die Verwendung von this.model kann in bestimmten Szenarien einen Fehler auslösen, wenn sich dies nicht auf ein Dokument/eine Instanz des Modells bezieht, sondern auf das eigentliche Modell selbst. Der sichere Weg, alle Szenarien zu behandeln und Fehler zu vermeiden, ist die Verwendung von mongoose.model ('User', UserSchema). – user3344977

+0

Das funktioniert für mich, danke. –

10

Das ist erwartetes Verhalten

Die unique: true entspricht einen Index in mongodb wie diese Einstellung:

db.myCollection.ensureIndex({ "email": 1 }, { unique: true }) 

diese Art der Validierung zu tun Mongoose mit (Mungo nennt diese komplexe Validierungs- IE- Sie sind nicht nur den Wert zu behaupten ist eine Zahl zum Beispiel), müssen Sie den Pre-Save-Ereignis verdrahten in:

mySchema.pre("save",function(next, done) { 
    var self = this; 
    mongoose.models["User"].findOne({email : self.email},function(err, results) { 
     if(err) { 
      done(err); 
     } else if(results) { //there was a result found, so the email address exists 
      self.invalidate("email","email must be unique"); 
      done(new Error("email must be unique")); 
     } else { 
      done(); 
     } 
    }); 
    next(); 
}); 
+0

Ihre Methode versucht, aber ein weiteres Problem aufgetreten: siehe http://stackoverflow.com/questions/13582862/mongoose-pre-save-async-middleware-not-working-as-expected – Olivier

Verwandte Themen