2016-05-14 38 views
0

Ich erkannte diese Frage hat beenaskedbefore, aber keine der Lösungen schien für mich zu arbeiten.Unique Validierung funktioniert nicht in Mongoose

Ich habe ein einfaches Modell ich so bin definieren:

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) 

Wenn ich die folgenden (in der REPL, so dass keine Asynchron-Ausgaben) laufen, würde ich erwarten, dass ein Fehler zu sehen, für die protokollierten der zweite Anruf an create.

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

Stattdessen sehe ich "ERROR" null.

Wenn ich eine count Abfrage oder eine find Abfrage ausführen, kann ich sehen, beide Modelle erstellt wurden. Was mache ich falsch?

bearbeiten

Hier sind einige der Dinge, die ich schon versucht habe:

  • Restart MongoDB nach Index Hinzufügen
  • alle vorhandenen Datensätze entfernen, so dass keine vorhandenen Datensätze sind das könnte die Eindeutigkeitseinschränkung verletzen
  • Definieren der email Attribut alle diese Möglichkeiten (ich habe verschiedene Implementierungen an verschiedenen Orten gesehen): { type: String, required: true, unique: true }, { type: String, required: true, index: true, unique: true }, { type: String, required: true, index: { unique: true } }.
+0

Können Sie Ihre Frage so bearbeiten, dass sie das enthält, was Sie mit den verknüpften Fragen ausgecheckt haben, damit wir diese Fragen nicht stellen müssen? – JohnnyHK

+0

@JohnnyHK Sicher, kein Problem. Aktualisiert. – LandonSchropp

Antwort

2

Dies ist sehr komplizierte Sache mit Knoten zu lösen, wie Sie es async kennen. Wenn Sie beide Abfragen parallel ausführen, prüfen beide, ob das Dokument zur selben Zeit existiert und beide versuchen, den Datensatz zu erstellen.

Es gibt zwei Dinge, die Sie tun können.

Eindeutiger Index erstellen

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

OR
Verwenden Aktualisierung mit $ setOnInsert

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

und vergewissern Sie sich der Index in mongoDB existiert.

Mongoose ändert den Index des Schlüsselsatzes nicht. Versuchen Sie zuerst, den Index von der Mongo-Shell zu entfernen.

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

Neustart Node Prozess und Mungoose wird jetzt Index mit eindeutigen Einschränkung erstellen.

+0

Ich glaube nicht, dass ich in meiner Frage klar war. Die Beispiele 'Subscriber.create' waren in der Knoten-REPL, so dass keine asynchronen Probleme auftreten sollten. Ich lief das erste Create, wartete darauf, dass es fertig war, und dann lief das zweite. Wenn ich später weitere Aufrufe von 'create' starte, sehe ich immer noch dieselben Probleme. – LandonSchropp

+0

Immer wenn Sie einen Index hinzufügen, müssen Sie den Knotenprozess neu starten. Mongoose autoIndex wird versuchen, Indizes sicherzustellen.Sie können das mit Mungo Debuggen sehen. Und stellen Sie sicher, Indizes sind in der Sammlung von * getIndexes() * – anwerj

+0

Ich habe versucht, den Server sowie Mongod neu starten, aber das scheint leider nicht zu helfen. Das Ausführen von 'Scheduler.collection.getIndexes()' führt zu folgendem Ergebnis: '{_id_: [['_id', 1]], email_1: [['email', 1]]}}. Ich sehe darin nichts über Einzigartigkeit, aber ich bin mir nicht sicher, ob ich es sollte, und ich weiß nicht, wie ich es beheben soll. – LandonSchropp

Verwandte Themen