---
title: MongoDB
editUrl: https://github.com/Cratis/Arc.TypeScript/edit/main/Documentation/mongodb/index.md
description: Serve model-bound queries from tenant-scoped MongoDB collections with BSON mapping, database-side paging, change-stream observation, and command read models.
---


Your read models live in MongoDB, and every tenant has its own database. Wiring a client, choosing the database per request, mapping concepts and GUIDs to BSON, and turning a change stream into a live query is the same code in every service. `@cratis/arc.mongodb` supplies it: your model declares its fields once, and the collection maps them to BSON and returns instances of your model.

:::caution[Source preview]
`@cratis/arc.mongodb` is optional and not published to npm. It uses the MongoDB 6 driver. The [capability reference](/arc/backend/typescript/reference/capabilities/#persistence-and-chronicle) has its status and the checks behind it.
:::

## What it provides

| Capability | Page |
| --- | --- |
| Register collections with `builder.withMongoDB(...)`, or from `Cratis:MongoDB` configuration, and inject them into queries | [Get started](/arc/backend/typescript/mongodb/getting-started/) |
| Choose a database, or a server, per tenant | [Tenancy](/arc/backend/typescript/mongodb/tenancy/) |
| Map decorated fields, concepts, GUIDs, and dates to BSON | [Serializers](/arc/backend/typescript/mongodb/serializers/) |
| Match Arc on .NET's property and collection naming | [Naming policies](/arc/backend/typescript/mongodb/naming-policies/) |
| Count, sort, and page in the database | [Paging](/arc/backend/typescript/mongodb/paging/) |
| Turn a change stream into an observable query | [Observing collections](/arc/backend/typescript/mongodb/observing-collections/) |
| Combine two or three live collections | [Joined observation](/arc/backend/typescript/mongodb/joined-observe/) |
| React to raw collection changes | [Change-stream watcher](/arc/backend/typescript/mongodb/change-stream-watcher/) |
| Store GeoJSON Point, LineString, and Polygon fields | [Geospatial types](/arc/backend/typescript/mongodb/geospatial/) |
| Load a read model by command key | [Command context](/arc/backend/typescript/commands/command-context/#load-a-read-model-by-key) |

`withMongoDB` registers a read-model resolver for the models you list in `readModels`, so a command can declare `@inject(commandReadModel(TaskRecord))` and receive the document whose identity equals the command key. Do not also register another integration, such as Chronicle, as the owner of the same type; `build()` fails when two claim one type.

:::caution[Storage does not authorize a caller]
Arc selects a tenant from the execution context, and the collection selects that tenant's database. Your authentication and authorization still have to verify that the caller may use that tenant and read those documents. Never pass untrusted request JSON directly to a MongoDB filter.
:::

## Low-level helper

The original `MongoReadModels<T, I>` remains for low-level `defineQuery` users. It takes a caller-owned client, `databaseForTenant`, and a trusted `filterFor(input, context)`. Its `queryPage` accepts Arc sorting only for fields listed in `sortableFields`, and caps pages at 100 by default. It has no change streams or field codecs; use the model-bound collection for those.

`MongoReadModels` returns raw driver documents. When they hold a protected Chronicle read model, set `readModel` to that class so Arc can release them. The class must also be registered with `withChronicle`; otherwise Arc has no release interceptor for it and serves the documents as stored. See [Release raw MongoDB documents](/arc/backend/typescript/chronicle/compliance/#release-raw-mongodb-documents).

## Current boundaries

This integration does not supply cross-store transactions or a durable change-stream checkpoint. The watcher shares a stream **within a tenant scope**, not across the process. Recognized transient reads retry at most twice; writes are not retried. Arc-owned clients expose OpenTelemetry MongoDB metrics, but caller-owned clients are not instrumented. Do not infer .NET's process-wide watcher or general-purpose resilience interceptors from these narrower guarantees. The [capability reference](/arc/backend/typescript/reference/capabilities/#persistence-and-chronicle) has the parity details.

Start with [Get started](/arc/backend/typescript/mongodb/getting-started/).
