Schema Validation
On this page
New in version 3.2.
MongoDB provides the capability to perform schema validation during updates and insertions.
You can implement schema validation in the UI for deployments hosted in MongoDB Atlas.
Specify Validation Rules
Validation rules are on a per-collection basis.
To specify validation rules when creating a new collection, use
db.createCollection()
with the validator
option.
To add document validation to an existing collection, use
collMod
command with the validator
option.
MongoDB also provides the following related options:
validationLevel
option, which determines how strictly MongoDB applies validation rules to existing documents during an update.validationAction
option, which determines whether MongoDB shoulderror
and reject documents that violate the validation rules orwarn
about the violations in the log but allow invalid documents.
JSON Schema
New in version 3.6.
Starting in version 3.6, MongoDB supports JSON Schema validation. To
specify JSON Schema validation, use the $jsonSchema
operator
in your validator
expression.
Note
JSON Schema is the recommended means of performing schema validation.
For example, the following example specifies validation rules using 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" } } } } } } })
For more information, see $jsonSchema
.
bsonType
definitions can be found on the BSON Types page.
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:
For example, the following example specifies validator rules using the query expression:
db.createCollection( "contacts", { validator: { $or: [ { phone: { $type: "string" } }, { email: { $regex: /@mongodb\.com$/ } }, { status: { $in: [ "Unknown", "Incomplete" ] } } ] } } )
Behavior
Validation occurs during updates and inserts. When you add validation to a collection, existing documents do not undergo validation checks until modification.
To perform validation checks on existing documents, use the
validate
command or the db.collection.validate()
shell helper.
Existing Documents
The validationLevel
option determines which operations MongoDB
applies the validation rules:
If the
validationLevel
isstrict
(the default), MongoDB applies validation rules to all inserts and updates.If the
validationLevel
ismoderate
, MongoDB applies validation rules to inserts and to updates to existing documents that already fulfill the validation criteria. With themoderate
level, updates to existing documents that do not fulfill the validation criteria are not checked for validity.
For example, create a contacts
collection with the following
documents:
db.contacts.insert([ { "_id": 1, "name": "Anne", "phone": "+1 555 123 456", "city": "London", "status": "Complete" }, { "_id": 2, "name": "Ivan", "city": "Vancouver" } ])
Issue the following command to add a validator to the contacts
collection:
db.runCommand( { collMod: "contacts", validator: { $jsonSchema: { bsonType: "object", required: [ "phone", "name" ], properties: { phone: { bsonType: "string", description: "must be a string and is required" }, name: { bsonType: "string", description: "must be a string and is required" } } } }, validationLevel: "moderate" } )
The contacts
collection now has a validator with the moderate
validationLevel:
If you attempted to update the document with
_id: 1
, MongoDB would apply the new validation rules since the existing document matches the criteria.In contrast, MongoDB will not apply validation rules to updates to the document with
_id: 2
as it does not meet the validation rules.
Starting in MongoDB version 5.0, the validator returns detailed error information when a validation condition isn't met. The error output is exhaustive - all errors are reported, not just the first one.
Important
The error output is intended for human consumption. It may change in the future and should not be relied upon in scripts.
In the next example, neither of the updates is consistent with the
validation rule we created above that requires name
to be a string.
db.contacts.update( { _id: 1 }, { $set: { name: 10 } } ) db.contacts.update( { _id: 2 }, { $set: { name: 20 } } )
The output below shows that the document with _id: 1
fails
validation with a detailed explanation, as shown in the errInfo
object. The update succeeds for the document with _id: 2
since this
document did not meet the initial criteria when validation was added.
// _id: 1 WriteResult({ "nMatched" : 0, "nUpserted" : 0, "nModified" : 0, "writeError" : { "code" : 121, "errmsg" : "Document failed validation", "errInfo" : { "failingDocumentId" : 1, "details" : { "operatorName" : "$jsonSchema", "schemaRulesNotSatisfied" : [ { "operatorName" : "properties", "propertiesNotSatisfied" : [ { "propertyName" : "name", "details" : [ { "operatorName" : "bsonType", "specifiedAs" : { "bsonType" : "string" }, "reason" : "type did not match", "consideredValue" : 10, "consideredType" : "double" } ] } ] } ] } } } }) // _id: 2 WriteResult({ "nMatched" : 1, "nUpserted" : 0, "nModified" : 1 })
To disable validation entirely, you can set validationLevel
to
off
.
Accept or Reject Invalid Documents
The validationAction
option determines how MongoDB handles
documents that violate the validation rules:
If the
validationAction
iserror
(the default), MongoDB rejects any insert or update that violates the validation criteria.If the
validationAction
iswarn
, MongoDB logs any violations but allows the insertion or update to proceed.
For example, create a contacts2
collection with the following JSON
Schema validator:
db.createCollection( "contacts2", { validator: { $jsonSchema: { bsonType: "object", required: [ "phone" ], properties: { phone: { bsonType: "string", description: "must be a string and is required" }, email: { bsonType : "string", pattern : "@mongodb\.com$", description: "must be a string and match the regular expression pattern" }, status: { enum: [ "Unknown", "Incomplete" ], description: "can only be one of the enum values" } } } }, validationAction: "warn" } )
With the warn
validationAction
, MongoDB logs any
violations but allows the insertion or update to proceed.
For example, the following insert operation violates the validation rule:
db.contacts2.insertOne( { name: "Amanda", status: "Updated" } )
However, since the validationAction
is warn
only, MongoDB only
logs the validation violation message and allows the operation to
proceed. Run the following command to view the MongoDB logs:
db.adminCommand( { getLog: "global" } )
Depending on collection usage, this command might return a lot of data. The validation error (one long line in the log, reformatted here for readability) contains information like this:
"{\"t\":{\"$date\":\"2021-01-20T15:59:57.305+00:00\"}, \"s\":\"W\", \"c\":\"STORAGE\", \"id\":20294, \"ctx\":\"conn1\", \"msg\":\"Document would fail validation\", \"attr\":{\"namespace\":\"test.contacts2\", \"document\":{\"_id\":{\"$oid\":\"6008537d42e0d23385568881\"}, \"name\":\"Amanda\", \"status\":\"Updated\"}, \"errInfo\":{\"failingDocumentId\":{\"$oid\":\"6008537d42e0d23385568881\"}, \"details\":{\"operatorName\":\"$jsonSchema\", \"schemaRulesNotSatisfied\":[ {\"operatorName\":\"properties\", \"propertiesNotSatisfied\":[ {\"propertyName\":\"status\", \"details\":[ {\"operatorName\":\"enum\", \"specifiedAs\":{\"enum\":[ \"Unknown\", \"Incomplete\"]}, \"reason\":\"value was not found in enum\", \"consideredValue\":\"Updated\"}]}]}, {\"operatorName\":\"required\", \"specifiedAs\":{\"required\":[\"phone\"]}, \"missingProperties\":[\"phone\"]}]}}}}"
Restrictions
You cannot specify a validator for collections in the admin
,
local
, and config
databases.
You cannot specify a validator for system.*
collections.
Bypass Document Validation
Users can bypass document validation using the
bypassDocumentValidation
option.
The following commands can bypass validation per operation using the
new option bypassDocumentValidation
:
applyOps
commandfindAndModify
command anddb.collection.findAndModify()
methodmapReduce
command anddb.collection.mapReduce()
methodinsert
commandupdate
command$out
and$merge
stages for theaggregate
command anddb.collection.aggregate()
method
For deployments that have enabled access control, to bypass document
validation, the authenticated user must have
bypassDocumentValidation
action. The built-in roles
dbAdmin
and restore
provide this action.