Browse documentation
MongoDB TutorialVerified with mongodb 7.5.0

Validate MongoDB Documents with JSON Schema

Add server-side MongoDB validation rules, test valid and invalid writes, and evolve an existing collection without losing schema flexibility.

What schema validation protects

MongoDB lets documents in a collection have different fields, but flexible storage does not require accepting every shape. Collection validation can reject writes with missing required fields, incorrect BSON types, values outside an allowed range, or combinations that violate a server-side rule.

Application validation and collection validation solve different problems. Application validation can produce friendly, workflow-specific messages before a request reaches MongoDB. Collection validation is the final shared guard for every writer that uses the database: application services, maintenance scripts, imports, and desktop tools.

Use validation after the important invariants are understood. Do not make optional fields required merely because today’s sample data happens to contain them.

Create a validated tutorial collection

This script recreates only the dedicated validated_products tutorial collection. It requires a user with permission to create and drop that collection.

use("mongog_tutorial");

const collectionName = "validated_products";
const exists = await db.listCollections(
  { name: collectionName },
  { nameOnly: true },
).hasNext();

if (exists) {
  await db.collection(collectionName).drop();
}

await db.createCollection(collectionName, {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["sku", "name", "price", "status"],
      properties: {
        sku: {
          bsonType: "string",
          minLength: 3,
          description: "sku must be a non-empty string",
        },
        name: { bsonType: "string" },
        price: {
          bsonType: "decimal",
          minimum: NumberDecimal("0"),
        },
        status: {
          enum: ["draft", "active", "retired"],
        },
        tags: {
          bsonType: "array",
          items: { bsonType: "string" },
        },
        createdAt: { bsonType: "date" },
      },
    },
  },
  validationLevel: "strict",
  validationAction: "error",
});

MongoDB’s $jsonSchema support is based on JSON Schema draft 4 with MongoDB-specific differences. Use bsonType when the BSON distinction matters—for example, decimal, date, or objectId.

Test a valid write

Create a document that satisfies every required rule:

const products = db.collection("validated_products");

const validResult = await products.insertOne({
  sku: "KB-VALID-01",
  name: "Validated keyboard",
  price: NumberDecimal("119.90"),
  status: "active",
  tags: ["peripheral", "tutorial"],
  createdAt: ISODate(),
});

print("Inserted:", validResult.insertedId);
products.findOne({ _id: validResult.insertedId });

The write is acknowledged and the stored price remains a BSON Decimal128 value. Validation does not transform data; it only checks whether the proposed document meets the rule.

Inspect an invalid write safely

The next document uses a JavaScript number instead of Decimal128 and an unapproved status. Catch the expected error so the tutorial can show the validation details without stopping later statements:

try {
  await products.insertOne({
    sku: "KB-INVALID-01",
    name: "Invalid keyboard",
    price: -10,
    status: "published",
  });
} catch (error) {
  print("Validation failed:", error.message);
  printjson(error.errInfo?.details ?? error.errInfo ?? {});
}

The insert is rejected. Depending on the server and error shape, errInfo can describe the failed schema operator, expected type, or disallowed value. Do not parse the human-readable error message as a stable application API.

Add validation to existing data

Before applying a strict rule to an existing collection, find documents that do not satisfy it. The same schema can be used inside a query:

const productSchema = {
  bsonType: "object",
  required: ["sku", "name", "price", "status"],
  properties: {
    sku: { bsonType: "string" },
    name: { bsonType: "string" },
    price: { bsonType: "decimal", minimum: NumberDecimal("0") },
    status: { enum: ["draft", "active", "retired"] },
  },
};

products.find({
  $nor: [{ $jsonSchema: productSchema }],
});

For a legacy migration, validationLevel: "moderate" can allow existing invalid documents to remain editable when an update does not make them newly subject to the rule. validationAction: "warn" allows invalid writes but records warnings in the server log. Both are migration tools, not substitutes for a cleanup plan.

Change a validator with the collMod database command after reviewing existing data:

await db.command({
  collMod: "validated_products",
  validator: { $jsonSchema: productSchema },
  validationLevel: "strict",
  validationAction: "error",
});

Handle additional properties carefully

Setting additionalProperties: false creates a closed field list. MongoDB automatically adds _id, so _id must also appear in properties or every normal insert will fail. Closed schemas also make gradual deployments harder when old and new application versions overlap.

Prefer validating critical fields and types unless the domain truly requires rejecting unknown fields. If you do close the schema, deploy compatible readers and writers before enabling the final rule.

Practice exercise

Extend the schema with an optional dimensions embedded document containing positive width and height numbers. Then:

  1. Insert a valid product with dimensions.
  2. Attempt to insert a product whose width is a string.
  3. Query the collection to prove only the valid product was stored.
  4. Remove only your exercise records by their tutorial SKU prefix.

This exercise tests nested properties, BSON type checking, predictable error handling, and safe cleanup.

Common mistakes

  • Assuming a flexible document model means server-side validation is unavailable.
  • Using JSON type where a BSON-specific bsonType rule is required.
  • Enabling a strict validator before auditing legacy documents and all active writers.
  • Setting additionalProperties: false without declaring the automatically generated _id field.
  • Treating validationAction: "warn" as enforcement; warned writes are still stored.
  • Expecting validation to cast a string into a date or number. Writers must send the correct BSON type.

Continue learning

Apply validation decisions alongside MongoDB data modeling, then process coordinated write sets with bulk operations. See the official MongoDB guides for schema validation and JSON Schema rules.