Mongster

Guides

Updates

The MongoDB update operators Mongster validates

Mongster validates every update operator it accepts against your schema. Each call to updateOne, updateMany, findOneAndUpdate, replaceOne, findOneAndReplace, or upsertOne runs the operator through the rules listed on this page before the document reaches the driver.

Mongster treats $set strictly — every key in the operator must exist on the schema, every value is type-checked, and null is rejected unless the field was declared with .nullable(). The sections below apply the same shape of validation to each operator, listing the rule that triggers a ValidationError.

Field paths use MongoDB dot notation. Nested arrays can be addressed with numeric indices (for example "tags.0").

[!NOTE] With withTimestamps() enabled, Mongster automatically appends $currentDate: { updatedAt: true } to your update, and $currentDate: { createdAt: true } on upserts. You do not need to include them yourself.

$set

Sets the value of one or more fields.

await .(
  { :  },
  { : { : "Rewrite the docs", : true } },
);

Rules:

  • The path must exist in the schema.
  • The value is type-checked against the schema field, with the field made optional for partial updates.
  • null is rejected unless the field was declared with .nullable().

$setOnInsert

Sets the value only when an upsert actually inserts a new document. Same path and value rules as $set, with one extra rule on _id.

await .(
  { :  },
  { : { : , : "new@example.com", : 0 } },
  { : true },
);

Rules:

  • The path must exist in the schema.
  • The value is type-checked against the schema field.
  • null is rejected unless the field was declared with .nullable().
  • _id is allowed here and must be an ObjectId.

$unset

Removes a field from the document.

await .(
  { :  },
  { : { : "" } },
);

Rules:

  • The path must exist in the schema.
  • The field must be optional (declared with .optional() or be nullable and present in the input).

$inc and $mul

Increment or multiply a numeric field by a number.

await .(
  { :  },
  { : { : 50 }, : { : 1.05 } },
);

Rules:

  • The target field must be a number schema.
  • The value must be a number.

$min and $max

Only updates the field if the new value is less than ($min) or greater than ($max) than the current value.

await .(
  { :  },
  { : { : 5 }, : { : 100 } },
);

Rules:

  • The path must exist in the schema.
  • The value is type-checked against the schema field (same shape as $set).
  • null is rejected unless the field was declared with .nullable().

$currentDate

Sets a field to the current date.

await .(
  { :  },
  { : { : true } },
);

Rules:

  • The target field must be a date schema.
  • The value may be true (set to current date), false (no-op), { $type: "date" }, or { $type: "timestamp" }.

$rename

Renames a field.

await .({}, { : { : "givenName" } });

Rules:

  • Both source and target paths must exist in the schema.
  • The source and target schemas must share an unwrapped type.

Array operators

OperatorValidation rule
$pushThe target field must be an array schema; each item is type-checked against the element schema.
$pullThe target field must be an array schema; the pull condition is type-checked against the element schema.
$addToSetThe target field must be an array schema; each item is type-checked. Supports { $each: [...] }.
$popThe target field must be an array schema; the value must be -1 or 1.
$pullAllThe target field must be an array schema; the value must be an array, each element type-checked.

$push and $addToSet accept an { $each: [...] } form when you want to push multiple values in one call. Each element of $each runs through the element schema.

await .(
  { :  },
  {
    : { : { : ["mongo", "odm"] } },
    : { : "typescript" },
    : { : "legacy" },
  },
);

$bit

Performs a bitwise update on an integer field. The value must be an object with exactly one of and, or, or xor.

await .({ :  }, { : { : { : 4 } } });
// or with and / xor
await .({ :  }, { : { : { : 7 } } });

Rules:

  • The target field must be a number schema.
  • The value must be an object with exactly one of and, or, or xor.
  • The chosen operator value must be an integer.

How replaceOne and upsertOne fit

replaceOne and findOneAndReplace use full-document parsing through schema.parse. The rules are the same as for a fresh insert — every required field must be present, every value type-checked.

upsertOne is sugar for updateOne(filter, parsedDoc, { upsert: true }). Mongster parses the document with the schema, then splits it:

  • $set for the body fields (without _id),
  • $setOnInsert: { _id } when _id is present.

See Model API for the upsert flow in detail.

On this page