Field Types, Missing Fields, Nulls, and Defaults

Be precise about what a field's absence means

MongoDB distinguishes a field that is missing from a field explicitly set to null. These states can carry different meanings.

For example:

  • Missing middleName: the person may not have supplied one.
  • middleName: null: the application explicitly represents the value as unknown or not applicable.
  • middleName: "": the application has stored an empty string, which is a third and often undesirable state.

Queries behave differently depending on the operator. A query { field: null } matches documents where the field is null or missing. Use $exists to test whether the field is present.

// Field is present, including when its value is null
db.users.find({ middleName: { $exists: true } });

// Field is missing
db.users.find({ middleName: { $exists: false } });

// Explicitly null, excluding missing fields
db.users.find({
  middleName: { $type: "null" }
});

Defaults are generally an application concern

MongoDB does not automatically apply arbitrary schema defaults merely because a field is described in JSON Schema. Set defaults in application logic, update pipelines, or a deliberate database workflow. If several services write to the same collection, centralize or standardize the defaulting policy.

Dates and identifiers

Use BSON Date values for timestamps, not inconsistent date strings. Store timestamps in UTC and convert to user-local time at the presentation boundary. Use ObjectId or a consistent chosen identifier type; avoid mixing strings and ObjectIds in the same reference field.

Arrays and scalar values

A field can contain arrays, but querying an array field has semantics that differ from querying a scalar. Schema validation can prevent accidental type drift, such as one writer storing tags as a string while another stores it as an array.

Renaming and removing fields

For a rename, use a staged migration rather than abruptly switching every reader and writer. For removal, first stop writing the field, then backfill or verify, then remove reader support when safe. This avoids breaking rolling deployments.

Specifications & Requirements
  • Missing:The document has no field with that name.
  • Null:The field exists and its value is BSON null.
  • $unset:Removes a field from a document.
Note

Choose a consistent meaning for missing, null, and empty values. Query behavior, uniqueness rules, validation, and application defaults can all be affected by this choice.

Find missing fields separately from explicit nulls
// Matches null OR missing
db.users.find({ middleName: null });

// Matches only documents where middleName exists
db.users.find({ middleName: { $exists: true } });

// Matches explicit BSON null
db.users.find({ middleName: { $type: "null" } });

// Remove a field entirely
db.users.updateOne(
  { _id: userId },
  { $unset: { middleName: "" } }
);
Key Takeaways
  • Do not treat missing, null, and empty string as interchangeable.
  • Store dates and references with consistent BSON types.
  • Define default values and schema migrations consistently across all writers.
Knowledge Check

Which query matches documents where `middleName` is explicitly BSON null but not missing?