MongoDB Schema Validation

MongoDB has a flexible document model, but an application still benefits from clear rules for required fields, BSON types, ranges, and allowed values. Schema validation applies these rules on the server whenever documents are inserted or updated.

Validation helps protect a collection from malformed data produced by scripts, migrations, older application versions, or manual writes. It complements application validation rather than replacing it.

Design validation from real document requirements. Rules that are too loose allow inconsistent data, while rules that are too strict can block legitimate application changes.

How MongoDB Schema Validation Works

A collection validator can use $jsonSchema, query expressions, or both. MongoDB supports a subset of JSON Schema draft 4 and adds bsonType so you can validate BSON-specific types such as objectId, date, int, and decimal.

Create a Collection with JSON Schema Validation

Pass a validator when you create the collection. Use required for mandatory fields and properties for field-specific rules.

Example:

// Create an orders collection with server-side validation
db.createCollection("orders", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["customerId", "status", "total", "createdAt"],
      properties: {
        customerId: {
          bsonType: "objectId",
          description: "customerId must be an ObjectId and is required"
        },
        status: {
          enum: ["pending", "paid", "shipped", "cancelled"],
          description: "status must be an allowed order state"
        },
        total: {
          bsonType: "decimal",
          minimum: 0,
          description: "total must be a non-negative Decimal128 value"
        },
        createdAt: {
          bsonType: "date",
          description: "createdAt must be a BSON date"
        }
      }
    }
  },
  validationLevel: "strict",
  validationAction: "error"
})

The description text can appear in validation error details, making a rejected write easier to diagnose.

Insert Valid Documents

BSON types matter. A JavaScript number is not automatically a Decimal128 value, and a text date is not a BSON date.

// This document satisfies every declared rule
db.orders.insertOne({
  customerId: ObjectId("64f0b55f9d4f3f2a1c8e1234"),
  status: "paid",
  total: Decimal128("1499.00"),
  createdAt: new Date()
})

Understand a Validation Error

An invalid insert or update fails with a document validation error when validationAction is error. Current server versions return details that identify failed operators and fields, but scripts should not depend on the exact human-readable error layout.

// Rejected: status is not allowed and total has the wrong BSON type
db.orders.insertOne({
  customerId: ObjectId(),
  status: "complete",
  total: 1499,
  createdAt: new Date()
})

Important JSON Schema Keywords

Keyword Use
bsonType Require one or more BSON types
required Require named properties
properties Define rules for individual fields
enum Allow only listed values
minimum and maximum Limit numeric values
minLength and maxLength Limit string length
items Validate array elements
additionalProperties Allow or reject undeclared fields

MongoDB does not support every JSON Schema keyword. For example, use BSON int or long instead of the JSON Schema integer type, and check the current manual before adopting a keyword.

Validate Nested Documents and Arrays

// Add nested shipping and line-item rules
{
  shipping: {
    bsonType: "object",
    required: ["city", "postalCode"],
    properties: {
      city: { bsonType: "string", minLength: 2 },
      postalCode: { bsonType: "string", pattern: "^[0-9]{6}$" }
    }
  },
  items: {
    bsonType: "array",
    minItems: 1,
    items: {
      bsonType: "object",
      required: ["sku", "quantity"],
      properties: {
        sku: { bsonType: "string" },
        quantity: { bsonType: "int", minimum: 1 }
      }
    }
  }
}

If you set additionalProperties: false, include _id in the allowed properties because MongoDB adds it to documents.

Add or Change Validation on an Existing Collection

Use the collMod database command. Existing documents are not automatically rewritten, so inspect them before enabling strict rejection.

// Replace the validator on an existing collection
db.runCommand({
  collMod: "orders",
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["status", "total"],
      properties: {
        status: { enum: ["pending", "paid", "shipped", "cancelled"] },
        total: { bsonType: "decimal", minimum: 0 }
      }
    }
  },
  validationLevel: "moderate",
  validationAction: "warn"
})

Choose a Validation Level

  • strict validates every insert and every updated document. It is the default.
  • moderate validates new documents and updates to documents that are already valid, while allowing some legacy invalid documents to be updated during migration.
  • off disables validation when supported by the selected operation and server version.

Choose a Validation Action

error rejects invalid writes and is the default. warn permits the write but records the violation in the server log, which is useful during rollout. MongoDB 8.1 added errorAndLog, which rejects and logs the violation; avoid it if you must downgrade to a version that does not support it.

Find Existing Invalid Documents

Use the same $jsonSchema expression inside a query. Wrap it in $nor to locate documents that do not match before changing enforcement.

// Find documents that fail the planned schema
db.orders.find({
  $nor: [{
    $jsonSchema: {
      bsonType: "object",
      required: ["status", "total"],
      properties: {
        status: { enum: ["pending", "paid", "shipped", "cancelled"] },
        total: { bsonType: "decimal", minimum: 0 }
      }
    }
  }]
})

Validation and Indexes

Validation controls document shape; indexes enforce uniqueness and improve query access. Use a unique index for a field such as an order number because JSON Schema cannot guarantee uniqueness across documents.

// Enforce uniqueness separately from document validation
db.orders.createIndex({ orderNumber: 1 }, { unique: true })

Best Practices

  • Test the schema against representative existing documents.
  • Use descriptive rules so errors explain the expected value.
  • Roll out with warn or moderate when legacy data needs migration.
  • Version validation changes alongside application changes.
  • Keep uniqueness and query performance requirements in indexes.
  • Monitor rejected writes and log warnings after deployment.

Conclusion

MongoDB schema validation keeps flexible documents within deliberate boundaries. Define BSON-aware rules, test valid and invalid writes, select the appropriate enforcement level and action, and migrate legacy data carefully. Combined with application validation and indexes, it provides a reliable data-quality layer at the database boundary.



Found This Page Useful? Share It!
Get the Latest Tutorials and Updates
Join us on Telegram