MongoDB
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.
What it provides
Section titled “What it provides”| Capability | Page |
|---|---|
Register collections with builder.withMongoDB(...), or from Cratis:MongoDB configuration, and inject them into queries | Get started |
| Choose a database, or a server, per tenant | Tenancy |
| Map decorated fields, concepts, GUIDs, and dates to BSON | Serializers |
| Match Arc on .NET’s property and collection naming | Naming policies |
| Count, sort, and page in the database | Paging |
| Turn a change stream into an observable query | Observing collections |
| Combine two or three live collections | Joined observation |
| React to raw collection changes | Change-stream watcher |
| Store GeoJSON Point, LineString, and Polygon fields | Geospatial types |
| Load a read model by command key | Command context |
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.
Low-level helper
Section titled “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.
Current boundaries
Section titled “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 has the parity details.
Start with Get started.