Schema validation in MongoDB

Schema validation in MongoDB

Even though MongoDb is schemaless which means that MongoDB documents does not need to have the same structure, fields, fields types, etc... But sometimes you want to force schema on some fields to keep homogeneity and structure of you documents for example a field views should be of type number and that is mandatory.

In those cases MongoDB gives us a solution which is MongoDB schema validators

Create schema validator in MongoDB

To create a validator we use The createCollection method with the parameters validator, validationLevel and validationAction (as the document of field validation, which document applying those validators to, and what will happen if validation fail, respectively).

Validator parameter

The validator option takes a document that specifies the validation rules or expressions. You can specify the expressions using the same operators as the query operators with the exception of $geoNear, $near, $nearSphere, $text, and $where.

validationLevel

Optional. Determines how strictly MongoDB applies the validation rules to existing documents during an update. validationLevel have 3 options:

  • "off": No validation for inserts or updates.
  • "strict": (Default). Apply validation rules to all inserts and all updates.
  • "moderate": Apply validation rules to inserts and to updates on existing valid documents. Do not apply rules to updates on existing invalid documents.

validationAction

Optional. Determines whether to error on invalid documents or just warn about the violations but allow invalid documents to be inserted. validationLevel have 2 options:

  • "error": (Default). Documents must pass validation before the write occurs. Otherwise, the write operation fails.
  • "warn": Documents do not have to pass validation. If the document fails validation, the write operation logs the validation failure.

Validation of documents only applies to those documents as determined by the validationLevel.

Types and examples of schema validator in MongoDB

JSON Schema

db.createCollection("students", {
   validator: {
      $jsonSchema: {
         bsonType: "object",
         required: [ "name", "year", "major", "address" ],
         properties: {
            name: {
               bsonType: "string",
               description: "must be a string and is required"
            },
            year: {
               bsonType: "int",
               minimum: 2017,
               maximum: 3017,
               description: "must be an integer in [ 2017, 3017 ] and is required"
            },
            major: {
               enum: [ "Math", "English", "Computer Science", "History", null ],
               description: "can only be one of the enum values and is required"
            },
            gpa: {
               bsonType: [ "double" ],
               description: "must be a double if the field exists"
            },
            address: {
               bsonType: "object",
               required: [ "city" ],
               properties: {
                  street: {
                     bsonType: "string",
                     description: "must be a string if the field exists"
                  },
                  city: {
                     bsonType: "string",
                     "description": "must be a string and is required"
                  }
               }
            }
         }
      }
   },
   	validationLevel: "moderate",
    validationAction: "warn"
})

Other Query Expressions

In addition to JSON Schema validation that uses the $jsonSchema query operator, MongoDB supports validation with other query operators, with the exception of the $near, $nearSphere, $text, and $where operators.

db.createCollection( "contacts",
   { validator: { $or:
      [
         { phone: { $type: "string" } },
         { email: { $regex: /@yamicode\.com$/ } },
         { status: { $in: [ "Unknown", "Incomplete" ] } }
      ]
   },
   validationAction: "error"
} )

Edit or add schema validator to existing collections using collMod

To add document validation to an existing collection, use collMod command with the validator option.

Syntax of collMod

db.runCommand( { 
	collMod: <collection or view>, 
	<option1>: <value1>, 
	<option2>: <value2> ...
} )

Example of collMod

db.runCommand( { collMod: "contact",
	validator: { $or:
      [
         { phone: { $type: "string" } },
         { email: { $regex: /@yamicode\.com$/ } },
         { status: { $in: [ "Unknown", "Incomplete" ] } }
      ]
   },
   validationAction: "error"
} )

Notes about schema validation

  • Validation occurs during updates and inserts. Existing documents do not undergo validation checks until modification.
  • You cannot specify a validator for collections in the admin, local, and config databases.
  • You cannot specify a validator for system.* collections.
  • JSON Schema is the recommended means of performing schema validation.
  • Users can bypass document validation using the bypassDocumentValidation option.