Rebuilding Projections
Projections can be completely rebuilt with the async daemon subsystem. Both inline and asynchronous projections can be rebuilt with the async daemon.
Rebuilds can be performed via the command line or in code as below.
For example, if we have this projection:
public class ShopProjection: SingleStreamProjection<Guid, Shop>
{
public ShopProjection()
{
Name = "Shop";
}
// Create a new Shop document based on a CreateShop event
public Shop Create(ShopCreated @event)
{
return new Shop(@event.Id, @event.Items);
}
}
We can rebuild it by calling RebuildProjectionAsync
against an async daemon:
private IDocumentStore _store;
public RebuildRunner(IDocumentStore store)
{
_store = store;
}
public async Task RunRebuildAsync()
{
using var daemon = await _store.BuildProjectionDaemonAsync();
await daemon.RebuildProjectionAsync("Shop", CancellationToken.None);
}
Optimized Projection Rebuilds 7.30
TIP
This optimization will be turned on by default in Marten 8, but we didn't want to force anyone using Marten 7 to have to upgrade their database without the explicit opt in configuration.
WARNING
Sorry, but this feature is pretty limited right now. This optimization is only today usable if there is exactly one single stream projection using any given event stream. If you have two or more single stream projection views for the same events -- which is a perfectly valid use case and not uncommon -- the optimized rebuilds will not result in correct behavior.
Marten can optimize the projection rebuilds of single stream projections by opting into this flag in your configuration:
builder.Services.AddMarten(opts =>
{
opts.Connection("some connection string");
// Opts into a mode where Marten is able to rebuild single
// stream projections faster by building one stream at a time
// Does require new table migrations for Marten 7 users though
opts.Events.UseOptimizedProjectionRebuilds = true;
});
In this mode, Marten will rebuild single stream projection documents stream by stream in the reverse order that the streams were last modified. This was conceived of as being combined with the FetchForWriting()
usage with asynchronous single stream projections for zero downtime deployments while trying to create less load on the database than the original "left fold" / "from zero" rebuild would be.
Rebuilding a Single Stream 7.28
A long standing request has been to be able to rebuild only a single stream or subset of streams by stream id (or string key). Marten now has a (admittedly crude) ability to do so with this syntax on IDocumentStore
:
await theStore.Advanced.RebuildSingleStreamAsync<SimpleAggregate>(streamId);