Mutations
create
Inserts a document and returns it after fetching it back. The _id is auto-generated if not provided.
const customer = await svc.create({
name: 'Alice',
status: 'active',
});
Pass projection to return only specific fields. The return type narrows to PartialDTO<T>:
const partial = await svc.create(input, { projection: ['_id', 'name'] });
Use createOnly when you don't need the created document back (slightly faster — no extra read):
await svc.createOnly(input);
update — PatchDTO
The standard way to update a document is to pass a partial object. Only the fields you include are changed; everything else is untouched. This is translated into a $set / $unset MongoDB update internally.
// Update one field
await svc.updateOnly(id, { status: 'inactive' });
// Update and get the result back
const updated = await svc.update(id, { name: 'Alice Smith', status: 'active' });
// Set a field to null → $unset (removes the field from the document)
await svc.updateOnly(id, { nickname: null });
Push / pull on arrays
To append or remove items from an array field without replacing the whole array, use the _$push and _$pull operators on the patch object:
// Append a tag
await svc.updateOnly(id, { _$push: { tags: 'vip' } });
// Remove specific tags
await svc.updateOnly(id, { _$pull: { tags: ['trial', 'pending'] } });
These map to MongoDB's $push and $pull operators respectively.
update — raw UpdateFilter
When you need full control over the MongoDB update pipeline (e.g. $inc, $addToSet, pipeline updates), pass a raw UpdateFilter<T> instead of a patch object. The two forms are mutually exclusive — the service detects which you're using by checking for $ prefixed keys.
import { UpdateFilter } from 'mongodb';
// Increment a counter
await svc.updateOnly(id, { $inc: { loginCount: 1 } } satisfies UpdateFilter<Customer>);
// Atomic conditional update using an aggregation pipeline
await svc.updateOnly(id, [
{ $set: { status: { $cond: [{ $gt: ['$balance', 0] }, 'active', 'suspended'] } } },
]);
updateMany
Applies a partial update (or raw UpdateFilter) to all documents matching the filter. Returns the number of matched documents.
// Deactivate all trial customers
const affected = await svc.updateMany(
{ status: 'suspended' },
{ filter: { status: 'trial', trialEndsAt: { $lt: new Date() } } },
);
replace
Replaces the entire document (except _id) and returns the new document.
const replaced = await svc.replace(id, {
name: 'Alice Smith',
status: 'active',
createdAt: original.createdAt, // preserve fields you want to keep
});
replace overwrites every field. Any field you omit is removed from the document. Prefer update when you only want to change specific fields.
delete / deleteMany
// Delete by id
const affected = await svc.delete(id); // returns 1 or 0
// Delete matching a filter
const affected = await svc.deleteMany({
filter: { status: 'inactive', updatedAt: { $lt: cutoff } },
});
Singleton mutations
MongoSingletonService methods work the same way but without an id argument:
// Create the singleton document (typically done once at startup)
await settings.for(ctx).createOnly({ theme: 'light', maintenanceMode: false });
// Partial update
await settings.for(ctx).updateOnly({ maintenanceMode: true });
// Replace
await settings.for(ctx).update({ theme: 'dark', maintenanceMode: false });
// Delete (rare — resets the singleton)
await settings.for(ctx).delete();
Full API reference
→ MongoCollectionService
→ MongoSingletonService
→ MongoPatchDTO