MongoDB $jsonSchema Operator

Beginner
6 min read
Updated: Oct 2026
3 examples
Live preview

What Is $jsonSchema?

$jsonSchema is a MongoDB query operator that checks whether a document matches a JSON Schema rules object. Use it in $match / find() to filter good documents, or attach the same rules as a collection validator to protect inserts and updates.

Remember
$jsonSchema = document must match these rules

{ $jsonSchema: {
    bsonType: "object",
    required: ["name", "age"],
    properties: {
      name: { bsonType: "string" },
      age:  { bsonType: "int", minimum: 0 }
    }
  }
}

find / $match  → filter matching docs
validator      → reject or warn on bad writes
prefer bsonType over type
UsePrefer
Full document shape$jsonSchema
One field type only$type
Field present / missing$exists

How to Use $jsonSchema in MongoDB

Write a schema once, then either filter with it or enforce it on writes.

  1. Describe the document: bsonType: "object", plus required and properties.
  2. To audit existing data, put that object inside find({ $jsonSchema: ... }) or $match.
  3. To protect new writes, pass the same object as a collection validator.
  4. For rollout, start with validationAction: "warn", then switch to "error".
PieceRequired?Role
bsonTypeUsuallyRoot and field BSON types
requiredNoFields that must exist
propertiesNoPer-field rules (type, min, enum…)
additionalPropertiesNoAllow or forbid extra fields

Pseudocode

Pseudocode
schema = {
  bsonType: "object",
  required: ["name", "age"],
  properties: {
    name: { bsonType: "string" },
    age:  { bsonType: "int", minimum: 0 }
  }
}

// Filter mode
for each document:
    if document matches schema:
        keep it
    else:
        skip it

// Validator mode (on insert/update)
if newDocument matches schema:
    accept write
else:
    error or warn (per validationAction)

Cheat Sheet

Keep these facts handy while writing validators.

TopicDetail
TypeQuery / validation operator (not $addFields)
Syntax{ $jsonSchema: { ...rules } }
Filter modefind / $match — returns matching docs
Enforce modeCollection validator — checks writes
TypesPrefer bsonType (int, date, …)
Common keywordsrequired, properties, enum, minimum
Sample rulename string + age int ≥ 0

Live Preview

Pick a sample document and see whether it passes a simple student schema (name string + age int ≥ 0.

Simulates { $jsonSchema: { required: ["name","age"], ... } }.

Result
document = { name: "Asha", age: 14 }

checks:
  required name ✓
  required age  ✓
  name is string ✓
  age is int ≥ 0 ✓

match → YES (kept by find / $match)

Worked Walkthrough — Student Shape

A class roster should always store a student name (string) and age (non-negative int). One document is valid; another is missing age.

Calculation
Schema:
  required: ["name", "age"]
  name → string
  age  → int, minimum 0

Doc A: { name: "Asha", age: 14 }
  name present + string ✓
  age present + int ≥ 0 ✓
  → MATCH

Doc B: { name: "Ravi" }
  age missing ✗
  → NO MATCH

find({ $jsonSchema: schema }) → only Doc A

MongoDB Examples

We use one small students collection. First insert sample docs, then filter with $jsonSchema, then show a collection validator. Run these in mongosh.

Example 1 — Sample Data

Imagine two student records. Asha has a complete shape; Ravi is missing age. We save them in a collection named students.

mongosh
db.students.insertMany([
  { _id: 1, name: "Asha", age: NumberInt(14) },
  { _id: 2, name: "Ravi" }
]);

How the Data Is Stored in MongoDB

After the insert, MongoDB keeps both documents in students. Run find() to see them:

mongosh
db.students.find()

Read those documents like this:

Field in MongoDBDoc 1Doc 2Plain English
_id12Document id
name"Asha""Ravi"Student name
age14(missing)Age in years
Picture
Schema wants:  name (string) + age (int ≥ 0)

  Asha  → name ✓  age ✓   MATCH
  Ravi  → name ✓  age ✗   FAIL

Next: find only the matching ones

How It Works

  1. Insert once. insertMany adds two student documents.
  2. Store age as int. NumberInt(14) keeps age as BSON int (shell 14 alone is a double).
  3. One is incomplete. Ravi has no age, so a schema that requires it will fail.

Example 2 — Filter with $jsonSchema

Goal: return only students that already match the schema (required name + age, correct types).

mongosh
db.students.find({
  $jsonSchema: {
    bsonType: "object",
    required: ["name", "age"],
    properties: {
      name: { bsonType: "string" },
      age: { bsonType: "int", minimum: 0 }
    }
  }
});

How It Works

  1. Same stored docs. MongoDB still has Asha and Ravi from Example 1.
  2. Apply the rules. $jsonSchema checks required fields and types.
  3. Keep matches only. Asha passes; Ravi is skipped because age is missing.

Example 3 — Collection Validator

Same schema, but this time MongoDB enforces it on new writes to a fresh collection named roster.

mongosh
db.createCollection("roster", {
  validator: {
    $jsonSchema: {
      bsonType: "object",
      required: ["name", "age"],
      properties: {
        name: { bsonType: "string" },
        age: { bsonType: "int", minimum: 0 }
      }
    }
  },
  validationAction: "error"
});

// OK
db.roster.insertOne({ name: "Asha", age: NumberInt(14) });

// Rejected — missing age
db.roster.insertOne({ name: "Ravi" });

How It Works

  1. Attach the schema. createCollection stores the same $jsonSchema as a validator.
  2. Valid write passes. Asha has name and age, so insert succeeds.
  3. Invalid write fails. With validationAction: "error", Ravi’s missing age is rejected.

Edge Cases & Pitfalls

Check these before shipping a validator to production.

types

Shell numbers are doubles

In mongosh, age: 14 is a double. For bsonType: "int", insert with NumberInt(14)—or allow both: bsonType: ["int", "double"].

modes

Filter ≠ enforce

find / $match only hide bad docs. Collection validators stop bad writes. Same schema, different job.

rollout

Warn before error

Start with validationAction: "warn" on existing collections, fix bad data, then switch to "error".

extra

additionalProperties

By default extra fields are allowed. Set additionalProperties: false only when you want a strict closed shape.

Performance Notes

ApproachCostBest for
find + $jsonSchemaPer-doc schema checkAudits / one-off cleanups
Collection validatorCheck on each writeOngoing data quality
Simple $type / $existsCheaper single-fieldOne-field filters

Keep schemas lean—only the fields you truly need. For hot paths, prefer $type or $exists when a full schema is overkill.

Key Takeaways

  • Role: match a document against JSON Schema rules.
  • Two modes: filter with find/$match, or enforce with a validator.
  • Types: prefer bsonType for MongoDB fields.
  • Sample: required name string + age int ≥ 0.

One line: $jsonSchema answers “does this document match my rules?”—for queries or for write protection.

Frequently Asked Questions

$jsonSchema checks whether a document matches a JSON Schema rules object. In find() or $match it returns documents that already satisfy the rules. As a collection validator it can reject or warn on inserts and updates that break the rules.
Use { $jsonSchema: { bsonType: "object", required: [...], properties: { ... } } }. The same schema object works in find/$match and in createCollection or collMod validators.
Prefer bsonType in MongoDB. It covers BSON types such as int, double, date, objectId, and bool. Remember: mongosh treats bare numbers as doubles, so use NumberInt() when your schema requires bsonType "int".
Use it in find() filters, $match aggregation stages, and as a collection validator via createCollection or collMod. It is a query/validation operator, not an aggregation expression like $addFields.
These apply only to collection validators. validationLevel is off, strict, or moderate. validationAction is error (reject invalid writes) or warn (allow but log). They do not apply to find/$match filters.
No. For one-field checks, $type and $exists stay simpler. Use $jsonSchema when you need a full document shape—required fields, nested rules, enums, and ranges together.

Next: $let

Define local variables for cleaner aggregation expressions.

$let tutorial →

About the author

Mari Selvan M P
Mari Selvan M P 🔗

Developer, cloud engineer, and technical writer

  • Experience 12 years building web and cloud systems
  • Focus Full Stack Development, AWS, and Developer Education

I write practical tutorials so students and working developers can learn by doing—from databases and APIs to deployment on AWS.

9 people found this page helpful