by Marc-David Militz
Forum: MongoDB Theorie
db.createCollection("recipes",
validator: {
$jsonSchema: {
<<Validation Rules>>
}
}
)
db.runCommand( {
collMod: "recipes",
validator: {
$jsonSchema: {
<<Validation Rules>>
}
}
} )
Innerhalb der Validator-Sektion des Dokumentes können wir explizit alle Felder aufführen, die das Dokument haben muss.
Wir können festlegen welche Werte die Felder enthalten dürfen, Minimum und/oder Maximum Werte Felder und ob es erlaubt ist dem Dokument weitere Felder hinzuzufügen.
Ein Beispiel mit einigen dieser Features wird helfen, die Funktionen etwas klarer zu machen.
db.createCollection("recipes", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name", "servings", "ingredients"],
additionalProperties: false,
properties: {
_id: {},
name: {
bsonType: "string",
description: "'name' is required and is a string"
},
servings: {
bsonType: ["int", "double"],
minimum: 0,
description:
"'servings' is required and must be an integer with a minimum of zero."
},
cooking_method: {
enum: [
"broil",
"grill",
"roast",
"bake",
"saute",
"pan-fry",
"deep-fry",
"poach",
"simmer",
"boil",
"steam",
"braise",
"stew"
],
description:
"'cooking_method' is optional but, if used, must be one of the listed options."
},
ingredients: {
bsonType: ["array"],
minItems: 1,
maxItems: 50,
items: {
bsonType: ["object"],
required: ["quantity", "measure", "ingredient"],
additionalProperties: false,
description: "'ingredients' must contain the stated fields.",
properties: {
quantity: {
bsonType: ["int", "double", "decimal"],
description:
"'quantity' is required and is of double or decimal type"
},
measure: {
enum: ["tsp", "Tbsp", "cup", "ounce", "pound", "each"],
description:
"'measure' is required and can only be one of the given enum values"
},
ingredient: {
bsonType: "string",
description: "'ingredient' is required and is a string"
},
format: {
bsonType: "string",
description:
"'format' is an optional field of type string, e.g. chopped or diced"
}
}
}
}
}
}
}
});
Wenn wir einen Blick auf das werfen, was wir hier definiert haben, dann sehen wir die Pflichtfelder "name", "servings" und "ingredients".
Die Regel "additionalProperties: false" verhindert, dass, über diese drei Felder hinaus, weitere Felder eingefügt werden, die wir nicht explizit zugelassen haben.
Wir haben das "_id" Feld in unseren Dokumenten zugelassen, was natürlich wichtig ist.
Wenn wir dieses Feld nicht zulassen kann man in die Collection keine Dokumente einfügen, da "_id" automatisch befüllt wird und den Primärschlüssel des Dokuments darstellt.
Das Feld "name" wurde als Pflichtfeld mit einem String als Inhalt definiert.
Das Feld "servings" ist ein Pflichtfeld und darf Integer oder Double Werte enthalten.
Als nächstes gibt es das optionale "cooking_method" Feld. Für dieses ist, sofern es im Dokument vorhanden ist, eine Liste zulässiger Werte definiert.
Das Feld "ingredients" hat einiges an zusätzlicher Komplexität in seinem Validierungsprozess.
Es ist als Array von Elementen definiert, welche wiederun "quantity", "measure", und "ingredient" als Pflichtfelder haben müssen.
Optional ist hier das Feld "format" vorgesehen, wo man eine Beschreibung wie "im Ganzen", "gewürfelt", "gehackt" oder ähnliches einfügen kann.
Welche Datentypen, von den einzelnen Feldern, akzeptiert werden ist durch den Schema-Validierungsprozess vorgegeben. Double oder Decimal für "quantity", einer der vordefinierten Werte für "measure" und ein String für "ingredient" und "format".
Mir den aktivierten Validierungsregeln können wir nun einige Beispieldokumente in die Collection einfügen und sehen was passiert.
db.recipes.insertOne({
name: "Chocolate Sponge Cake Filling",
servings: 4,
ingredients: [
{
quantity: 7,
measure: "ounce",
ingredient: "bittersweet chocolate",
format: "chopped"
},
{ quantity: 2, measure: "cup", ingredient: "heavy cream" }
]
});
Das Einfügen funktioniert, da alle Pflichtfelder innerhalb der Validierungsregeln vorhanden und befüllt sind.
db.recipes.insertOne({
name: "Chocolate Sponge Cake Filling",
servings: 4,
ingredients: [
{
quantity: 7,
measure: "ounce",
ingredient_name: "bittersweet chocolate",
format: "chopped"
},
{ quantity: 2, measure: "cup", ingredient: "heavy cream" }
],
directions:
"Boil cream and pour over chocolate. Stir until chocolate is melted."
});
Das Einfügen dieses Dokuments wird mit der Fehlermeldung "WriteError: Document failed validation" fehlschlagen, weil es das zusätzliche Feld "directions" enthält.
Es gibt noch eine ganze Reihe weiterer Regeln, die man auf Dokumente anwenden kann
https://docs.mongodb.com/master/reference/operator/query/jsonSchema/#doc-insert-schema-validation
außerdem kann man die Schema-Validierung auch auf Subdokumente, wie wir das mit den "ingredients" gemacht haben, und auf Arrays anwenden.
Zudem kann man Schema-Abhängigkeiten setzen, um Applikationslogik nativ in der Datenbank zu verankern.
Des Weiteren lässt sich die "validation strictness" beeinflussen, was es erlaubt festzulegen ob es einen Fehler oder nur eine Warnmeldung gibt.
https://docs.mongodb.com/manual/core/schema-validation/#specify-validation-rules