Flexible Schema: Benefits, Limitations, and Validation
MongoDB collections can contain documents with different fields and structures. This is commonly called a flexible schema.
For example, a collection might contain these documents:
{ name: "Arun", age: 28 }
{ name: "Meera", email: "meera@example.com", skills: ["React"] }
{ name: "Ravi", age: 32, department: "Engineering" }
MongoDB can store all three documents in the same collection. A query that expects age will not match every document, and an application that assumes email always exists must account for documents where it is absent.
Flexible does not mean structureless
A production application typically defines a logical schema even if the database does not require every field to exist in every document.
For example, a user record may require:
nameto be a string.emailto be a string.createdAtto be a date.isActiveto be a Boolean.
Without appropriate validation, one service might store age as a number while another stores it as a string. These inconsistent types can make filters, sorting, aggregation, and application code harder to reason about.
MongoDB schema validation
MongoDB supports collection-level validation using JSON Schema rules and other supported validation expressions.
db.createCollection("validatedUsers", {
validator: {
$jsonSchema: {
bsonType: "object",
required: ["name", "email", "createdAt"],
properties: {
name: {
bsonType: "string",
minLength: 1
},
email: {
bsonType: "string",
minLength: 3
},
createdAt: {
bsonType: "date"
},
age: {
bsonType: ["int", "long", "double", "decimal"],
minimum: 0
}
}
}
},
validationLevel: "strict",
validationAction: "error"
});
This creates a collection that requires name, email, and createdAt, with the specified types and constraints. The age field is optional but, if present, must use an accepted numeric BSON type and be nonnegative.
validationLevel: "strict" applies validation to inserts and updates under the configured rules. validationAction: "error" rejects operations that produce invalid documents.
Schema evolution
As an application grows, you may need to change its document structure. A safe migration can involve adding new fields, temporarily supporting old and new shapes, backfilling existing documents, updating application code, and eventually removing deprecated fields.
Do not assume that changing a Mongoose schema automatically migrates every document already stored in MongoDB. Application-level schemas and database-level validation are separate mechanisms.
A flexible schema allows different document structures, but it does not guarantee that the stored data follows your application's intended contract. Use application validation, MongoDB schema validation, and migrations where appropriate.
db.schemaDemo.insertMany([
{ name: "Arun", age: 28 },
{ name: "Meera", age: "29" },
{ name: "Ravi" }
]);
// Matches numeric age values of at least 25.
db.schemaDemo.find({ age: { $gte: 25 } });
// Find documents where age is missing.
db.schemaDemo.find({ age: { $exists: false } });
// Find documents where age is stored as a string.
db.schemaDemo.find({ age: { $type: "string" } });"29" as the number 29. $exists: false finds documents without the field, and $type: "string" identifies documents whose age field has the string BSON type. These differences illustrate why flexible schemas should be paired with deliberate validation and migration practices.- Documents in a collection can have different fields.
- Missing fields and fields with inconsistent types can cause application bugs.
- MongoDB supports collection-level JSON Schema validation.
- Strict validation can reject writes that violate configured rules.
- Changing an application schema does not automatically migrate existing database documents.
What happens when a collection has strict schema validation with validationAction set to error and a write violates the rules?