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.
nullis 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.
nullis rejected unless the field was declared with.nullable()._idis allowed here and must be anObjectId.
$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). nullis 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
| Operator | Validation rule |
|---|---|
$push | The target field must be an array schema; each item is type-checked against the element schema. |
$pull | The target field must be an array schema; the pull condition is type-checked against the element schema. |
$addToSet | The target field must be an array schema; each item is type-checked. Supports { $each: [...] }. |
$pop | The target field must be an array schema; the value must be -1 or 1. |
$pullAll | The 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, orxor. - 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:
$setfor the body fields (without_id),$setOnInsert: { _id }when_idis present.
See Model API for the upsert flow in detail.