Mongoose: Die Modellaktualisierungsmethode respektiert keine Validatoren

Erstellt am 24. Apr. 2012  ·  59Kommentare  ·  Quelle: Automattic/mongoose

Ich kann die Methode model.Update verwenden, um unabhängig von Schemabeschränkungen auf einen beliebigen Wert zu aktualisieren

Wenn ich beispielsweise ein Schema mit einer Aufzählungseigenschaft habe, kann ich mit update auf jeden Wert außerhalb der Aufzählungsbeschränkung ändern, wodurch der Satz ungültig wird.

Das erwartete Verhalten bestand darin, einen Fehler auszulösen, wenn der aktualisierte Wert nicht validiert wurde.

Ich schlage eine zusätzliche Option für die Update-Methode vor, um beim ersten Fehler zu beenden oder nicht.

new feature

Hilfreichster Kommentar

+1

Es ist völlig unintuitiv, dass das Update nicht verwendet: Standardwerte, Setter, Validierung und Aufzählungen. Was nützt ein Schema, wenn die Kernoperationen sich nicht daran halten.

Alle 59 Kommentare

Möglicherweise möchten Sie die Schemaeinstellung strict aktivieren, die alle ungültigen Schemapfade ignoriert und den Rest aktualisiert. kein Fehler wird geworfen.

neues Schema({..}, { strict: true })

Es gibt eine ähnliche Pull-Anforderung, die darauf wartet, zusammengeführt zu werden, die ausgelöst wird, wenn Pfade festgelegt werden, die im Schema nicht vorhanden sind, aber nicht während model.update . vielleicht sollten wir das oben zum PR hinzufügen und den Fehler an den Rückruf übergeben.

Hallo nochmal, danke für deine schnelle Antwort.

Ich bezog sich nicht auf ungültige Pfade, sondern auf Einschränkungen innerhalb eines bestimmten Pfads.

Nimm dieses Beispiel

var Benutzer = neues Schema({
Nutzername: {
Typ: Zeichenfolge,
Kleinbuchstaben: wahr,
trimmen: wahr,
einzigartig: wahr
},
Name: {
Typ: Zeichenfolge,
trimmen: wahr,
erforderlich: wahr,-
einzigartig: falsch,-
Index: wahr
},
Passwort: {
Typ: Zeichenfolge,
erforderlich: wahr,-
wählen: falsch,
set: verschlüsseln
},
Rolle: {
Typ: Zeichenfolge,
"Standardbenutzer',
"enum": ['user', 'admin', 'root']
},
erstellt: {
Typ: Datum,
"default": Datum.jetzt
}
}, { strikt: wahr });

users.update({"Benutzername" : "test"}, {"Rolle" : "thisShowldFail"}, Funktion (err, val){
...
});

Beachten Sie, dass der Benutzer "test" jetzt die Rolle "thisShowldFail" hat, auch wenn die strikte Schemaoption aktiviert ist.
Sollte Update Enumerationen und andere ähnliche Optionen nicht respektieren?

Sie haben Recht, es sollte Enumerationen validieren. Ich dachte, dafür gibt es irgendwo ein Ticket.

+1, kann #update wegen dieses Problems nicht verwenden.

Ist es möglich, .update alles machen zu lassen, was ein neues Dokument + .save tun würde?

  • Standardeinstellungen
  • Setter
  • benutzerdefinierte Validierungen
  • aufzählen

wenn die Upsert-Option verwendet wird, auch

  • erforderlich

derzeit nicht

Ich meine, ist es möglich/geplant zu implementieren ... ? :)

es könnte schön sein. verwandte #472

+1

Es ist völlig unintuitiv, dass das Update nicht verwendet: Standardwerte, Setter, Validierung und Aufzählungen. Was nützt ein Schema, wenn die Kernoperationen sich nicht daran halten.

+1

Ich liebe Mungo, aber wenn es Updates nicht validiert, ist es für mich viel weniger hilfreich. Ich habe große Dokumente und möchte sie nicht nur zur Validierung herunterladen.

Hier springe ich ein. Ich tauche ein bisschen ein und versuche, dies umzusetzen.
Das Ziel ist zu erhalten:

  • Standardeinstellungen
  • Setter
  • Validierungen
  • aufzählen
  • erforderlich

Ich bin mir nicht einmal sicher, ob ich erfolgreich sein werde, aber ich werde es versuchen. Ich werde mit Validatoren beginnen.

Wünsch mir viel Glück!

Merc.

+1

+1

Wäre toll gewesen, wenn .update Validierungen unterstützen würde.

Stoß +1

Unebener Stoß +1

Bitte fügen Sie beim Update Validierungen hinzu!

+1

Bearbeiten: -2, weil ich nicht glaube, dass Mungo die Validierung übernehmen sollte. Wenn Sie eine Validierung wünschen, sollten Sie eine andere spezialisierte Bibliothek verwenden, z

@thalesfsp Ja. Es wurde in der Vergangenheit versucht, aber die Regeln werden sehr ungenau, da kein Dokument im Speicher vorhanden ist und unter verschiedenen Umständen zusammenbrechen, wodurch das Verhalten inkonsistent und verwirrend wird.

Die Schönheit von Open Source: Wenn Sie ein Feature wünschen, können Sie es schreiben und einen Pull-Request mit bestandenen Tests und einer Dokumentation einreichen, die beweist, dass es richtig funktioniert.

Eine ziemlich gravierende Einschränkung. Wäre es bei der Verfolgung eines Patches praktisch, das Schema-Objekt direkt zu crawlen, um zu bestimmen, ob ein Validator ausgeführt werden sollte? Ich kümmere mich hauptsächlich um benutzerdefinierte Validatoren und Aufzählungsregeln, die auf das Update angewendet werden. Die anderen Schemaeinschränkungen sollten meiner Meinung nach beim Speichern des Dokuments bereits angewendet worden sein. Ist eine solche Vereinfachung des Problems auf nur Enumerationen und Validatoren sinnvoll und macht es nicht erforderlich, während des Updates ein Dokument zur Verfügung zu haben?

+1 Bump, dies wäre eine sehr nützliche Funktion - bei Updates möchte ich, dass Mins / Maxes usw. aus dem Schema respektiert werden - ansonsten mache ich viel Boilerplate-Logik für etwas, was Mungo tun kann

Es wäre großartig, dies zu sehen. Im Moment besteht meine Problemumgehung darin, das Objekt zu finden, die Felder zu ändern und es dann zu speichern, wodurch die Validierungs-Middleware ausgelöst wird. Laut den Dokumenten :

Tank.findById(id, function (err, tank) {
  tank.size = 'large';
  tank.save(function (err) {
   // Document updated, do something with it
  });
});

Ich verstehe, dass dies schwierig ist, da der Befehl update direkt an Mongo delegiert und das vollständige Dokument nicht im Speicher liegt, um validiert zu werden. Der von @BrianHoldsworth vorgeschlagene ausführt , die aktualisiert werden sollen.

@aheckmann könnten Sie uns mehr Details zu den vorherigen (fehlgeschlagenen) Implementierungsbemühungen geben, damit jeder, der diesen Patch versucht, nicht noch einmal die gleichen Fehler macht?

Ich kümmere mich hauptsächlich um benutzerdefinierte Validatoren und Aufzählungsregeln, die auf das Update angewendet werden. Die anderen Schemaeinschränkungen sollten meiner Meinung nach beim Speichern des Dokuments bereits angewendet worden sein. Ist eine solche Vereinfachung des Problems auf nur Enumerationen und Validatoren sinnvoll und macht es nicht erforderlich, während des Updates ein Dokument zur Verfügung zu haben?

@BrianHoldsworth Ich denke, dies könnte eine zu required: true aktualisiert wird, um eine leere Zeichenfolge zu sein? Wir benötigen dies, um einen Validierungsfehler auszulösen.

Das interessiert mich auch. Vielleicht könnte ein Plug-In geschrieben werden, um die Methode .update() zu überschreiben und die Validierung auszuführen? So kann auch eine Teillösung realisiert werden. Wäre es dagegen im Kern, würde man erwarten, dass es jede Art von Validierung handhabt und 100% robust ist.

Ich bin auch darauf gestoßen, sowohl mit benutzerdefinierten Validatoren als auch mit Enumerationen. Obwohl ein Suchen und dann eine Aktualisierung möglich ist, ist es sehr schwierig, allgemeinen Fallcode zu schreiben, wenn Dokumente unterschiedliche Unterdokumentstrukturen haben.

+1 Stoß das.

Brians Lösung scheint ziemlich elegant zu sein. Würde gerne benachrichtigt werden, wenn Patches in die Beta-Phase kommen.

+1

brauche das +1

+1

+1

+1

+1

In 3.9.3 hat update() 2 spezielle Optionen, setDefaultsOnInsert und runValidators , die Standardeinstellungen festlegen und Validatoren für Ihre Abfrage ausführen. Siehe Tests zum Beispiel, noch keine echten Dokumente :(

Vielen Dank - das ist eine großartige Lösung!

@vkarpov15 Ich habe Ihren Code verwendet, um auch die Validierung auf findOneAndUpdate anzuwenden. Siehe PR-Nr. 2393.

Hallo, wissen Sie, wann die stabile Version 3.9 veröffentlicht wird, um die Validierung beim Update zu verwenden?

Vielen Dank

@AlexandreAWE gute Frage. Ich bin gerade dabei, die Dinge mit 4.0 abzuschließen und den 3.9.x-Zweig Beta zu testen, aber im Moment ist es eine "Es wird erledigt, wenn es fertig ist". Ich hoffe, dass ich vor Weihnachten einen RC haben werde.

@vkarpov15 Wie

@andrewholsted wartet darauf, dass sich der mongodb-Treiber 2.0 und der mongodb-Server 2.8 stabilisieren - das passiert hoffentlich diesen Monat, kann aber 4.0 nicht wirklich liefern, ohne die neueste Version von mongodb und den neuesten Treiber zu unterstützen. Siehe meinen Blog für ein wenig mehr Details.

Potenziell dumme Frage von mir, aber warum nicht die Daten, die aktualisiert werden, gegen das Schema validieren, bevor sie an mongodb übergeben werden?

Außerdem +1

markieren und warten

Kann es kaum erwarten, bis 3.9 stabil ist :)

Ist diese Funktion schon drin? Warte gespannt auf 3.9.. Wann wird es verfügbar sein?

Sie können npm install mongoose@unstable um die instabile Version zu erhalten. Die aktuelle ETA für 4.0 ist der 25. März - ein guter Ort, um dies zu überprüfen, ist die Seite mit den

Bin gerade gestern Abend auf dieses Problem gestoßen. Gut, dass ich nicht der einzige bin! Ich freue mich auf die Veröffentlichung dieser Änderung, danke für alles, was Sie tun!

+1

Ich weiß nicht, warum dieses Problem als geschlossen gekennzeichnet ist. Ich stehe immer noch davor.

Ich bin mir eigentlich nicht sicher, ob dies bei der Enum-Validierung für findOneAndUpdate() funktioniert, selbst wenn runValidators auf true gesetzt ist.

@m1cah Bitte geben Sie ein Beispiel an, das zeigt, was Sie tun

@vkarpov15 Ich glaube, dies ist ein kurzes Beispiel, das es demonstriert: http://code.runnable.com/VYhGbVhereIYdbst/update-validation-enum-for-mongoose-and-databases

Nun, ein Problem ist, dass das obige Beispiel eine prähistorische Version von Mungo verwendet:

root<strong i="6">@runnable</strong>:~# head node_modules/mongoose/package.json                                                                                                                 
{                                                                                                                                                                         
  "name": "mongoose",                                                                                                                                                     
  "description": "Elegant MongoDB object modeling for Node.js",                                                                                                           
  "version": "3.6.14",                                                                                                                                                    
  "author": {                                                                                                                                                             
    "name": "Guillermo Rauch",                                                                                                                                            
    "email": "[email protected]"                                                                                                                                   
  },                                                                                                                                                                      
  "keywords": [                                                                                                                                                           
    "mongodb",  

Versuchen Sie, auf 4.x zu aktualisieren, und es sollte funktionieren.

Sind Sie sicher, dass es mit einer Enum- und findOneAndUpdate-Methode funktioniert?
Auf Mungo 4.2.6 scheint es zu scheitern, ich kann einen schlechten Wert einstellen.

Schema:

var UserSchema = new Schema({
    first_name: {
        type: String,
        required: true,
    },
    last_name: {
        type: String,
        required: true,
    },
    email: {
        type: String,
        unique: true,
        required: true,
    },
    embededData: [{
        type: {
            type: String,
            enum: ['value1', 'value2', 'value3']
            required: true
        }
    }]
}, { strict: true });

FindOneAndUpdate-Methode:

UserModel.findOneAndUpdate(
    {_id: uid}, 
    {$push: {embededData: data}}, 
    { runValidators: true }, function(err) {
});

Dann kann ich embededData.type = 'Panda'; schieben

Siehe Update-Validator-Dokumente und #2933 - Update-Validatoren werden nicht auf $push , sondern nur auf $set und $unset

+1

Soweit ich sehen kann, funktioniert dies immer noch nicht für den Fall, dass Sie einen benutzerdefinierten Validator für ein Feld verwenden, das ein Array ist.

Zum Beispiel dieses Code-Snippet:

var mongoose = require('mongoose');
mongoose.connect('mongodb://localhost/myTestDB');

var db = mongoose.connection;

db.on('error', function (err) {
console.log('connection error', err);
});
db.once('open', function () {
console.log('connected.');
});

var Schema = mongoose.Schema;
var userSchema = new Schema({
  _id : String,
  name : {
    type: [String],
    validate: {
        validator: function (str) {
            return str.length > 1
        }
    },
  }
});


var User = mongoose.model('User', userSchema);

User.findOneAndUpdate({"name": ["John", "Doe"]}, { 
  $setOnInsert: {
    name: ["John"],
  },
}, { runValidators: true, upsert: true, new: true }, function (err, data) {
  if (err) {
    return console.log(err);
  } else {
    // console.log(data.validateSync())
    return console.log('Updated', data);
  }
});

ermöglicht es Ihnen, den Benutzer so zu aktualisieren, dass er ein name Feld von ["John"] hat, ohne Fehler auszulösen, obwohl der benutzerdefinierte Validator, den ich eingefügt habe, ausdrücklich jedes Namens-Array mit einer Länge von kleiner oder gleich 1 verbietet Der validator selbst funktioniert einwandfrei, was daran zu erkennen ist, dass wenn Sie die Zeile console.log(data.validateSync()) auskommentieren und dadurch die Validierung erzwingen, tatsächlich die entsprechende Fehlermeldung zurückgegeben wird. Das Problem ist, dass diese Validierung nicht innerhalb des findOneAndUpdate() Aufrufs stattfindet, obwohl ich die Option runValidators=true einbeziehe.

Sieht nach einem Bug aus, kannst du dafür ein separates Thema eröffnen?

Vielen Dank

Gibt es eine Lösung für das obige Problem? @vkarpov15

@ Saravanan90 Bitte hören Sie auf, lange geschlossene Probleme ohne aussagekräftige Informationen zu kommentieren. Öffnen Sie ein separates Problem mit Codebeispielen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen