← Back to MongoDB Mastery
Intermediate16 min read

Schema Validation

Enforce document structure with JSON Schema validation rules and constraints.

Why Validate in MongoDB

MongoDB flexible schema does not mean schema-less. Without validation, inconsistent documents accumulate silently and break application assumptions. Collection-level validation catches bad data at the database boundary.

Combine application validation (for user-friendly errors) with MongoDB validation (for integrity). Validation rules apply to inserts and updates unless configured otherwise.

  • Validation prevents malformed documents from entering the database
  • Rules are versioned with your deployment pipeline
  • Invalid writes fail with a WriteError describing the violation

JSON Schema Validation

Use collMod or create with validator and $jsonSchema to define required fields, types, enums, and nested object shapes. MongoDB supports a subset of JSON Schema draft 4.

Start with validationLevel: "moderate" to validate only inserts and updates that match the schema shape, allowing legacy documents to coexist during migrations.

db.createCollection("users", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["email", "name"],
      properties: {
        email: { bsonType: "string", pattern: "^[^\s@]+@[^\s@]+\.[^\s@]+$" },
        name: { bsonType: "string", minLength: 1 },
        age: { bsonType: "int", minimum: 0 }
      }
    }
  },
  validationLevel: "strict",
  validationAction: "error"
})

Validation Rules and Actions

validationAction: "error" rejects invalid documents; "warn" logs violations but allows the write (useful during migration). validationLevel: "strict" validates all inserts and updates; "moderate" skips full validation on documents that do not match the schema shape.

Test validators in staging with representative documents, including edge cases like null, missing optional fields, and array bounds.

db.runCommand({
  collMod: "users",
  validator: { $jsonSchema: { /* updated schema */ } },
  validationLevel: "moderate"
})

Enforcing Data Types

Use bsonType to restrict fields to string, int, long, double, bool, date, object, array, and others. Mixed types in the same field break queries and indexes—validation enforces consistency.

For monetary values, prefer Decimal128 over double to avoid floating-point rounding errors. Store dates as BSON Date, not ISO strings, for correct range queries and sorting.

properties: {
  price: { bsonType: "decimal" },
  createdAt: { bsonType: "date" },
  tags: { bsonType: "array", items: { bsonType: "string" } }
}

Constraints and Migration

Unique indexes complement validation by enforcing uniqueness at the database level. Check constraints beyond JSON Schema may require application logic or aggregation-based audits.

When tightening validation on existing collections, run a one-time migration script to fix non-conforming documents before switching validationLevel to strict. Document the schema version in a metadata collection for team visibility.

  • Pair required fields in schema with sensible defaults in application code
  • Use $jsonSchema additionalProperties: false to reject unknown fields during strict migrations
  • Audit validation failures in logs to catch client bugs early

Get In Touch


Ready to discuss your next project? Drop me a message.