Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

FetchLatest API for single stream aggregations #3592

Merged
merged 2 commits into from
Dec 12, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion docs/.vitepress/config.mts
Original file line number Diff line number Diff line change
@@ -172,7 +172,8 @@ const config: UserConfig<DefaultTheme.Config> = {
text: 'Aggregate Projections', link: '/events/projections/aggregate-projections', items: [
{ text: 'Live Aggregations', link: '/events/projections/live-aggregates' },
{ text: 'Multi-Stream Projections', link: '/events/projections/multi-stream-projections' },
{ text: 'Explicit Aggregations', link: '/events/projections/custom-aggregates' },]
{ text: 'Explicit Aggregations', link: '/events/projections/custom-aggregates' },
{ text: 'Reading Aggregates', link: '/events/projections/read-aggregates'}]
},
{ text: 'Event Projections', link: '/events/projections/event-projections' },
{ text: 'Custom Projections', link: '/events/projections/custom' },
2 changes: 1 addition & 1 deletion docs/diagnostics.md
Original file line number Diff line number Diff line change
@@ -24,7 +24,7 @@ builder.ConfigureServices(services =>
opts.DisableNpgsqlLogging = true;

opts.Events.AppendMode = EventAppendMode.Quick;
opts.Events.UseIdentityMapForInlineAggregates = true;
opts.Events.UseIdentityMapForAggregates = true;

opts.Projections.Add<DaemonTests.TestingSupport.TripProjection>(ProjectionLifecycle.Inline);
});
6 changes: 3 additions & 3 deletions docs/documents/identity.md
Original file line number Diff line number Diff line change
@@ -552,7 +552,7 @@ public class LimitedDoc
public LowerLimit Lower { get; set; }
}
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/ValueTypeTests/linq_querying_with_value_types.cs#L105-L120' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_limited_doc' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/ValueTypeTests/linq_querying_with_value_types.cs#L127-L142' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_limited_doc' title='Start of snippet'>anchor</a></sup>
<a id='snippet-sample_limited_doc-1'></a>
```cs
[ValueObject<long>]
@@ -590,7 +590,7 @@ And the `UpperLimit` and `LowerLimit` value types can be registered with Marten
opts.RegisterValueType(typeof(UpperLimit));
opts.RegisterValueType(typeof(LowerLimit));
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/ValueTypeTests/linq_querying_with_value_types.cs#L20-L27' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_registering_value_types' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/ValueTypeTests/linq_querying_with_value_types.cs#L21-L28' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_registering_value_types' title='Start of snippet'>anchor</a></sup>
<a id='snippet-sample_registering_value_types-1'></a>
```cs
// opts is a StoreOptions just like you'd have in
@@ -628,7 +628,7 @@ public async Task store_several_and_order_by()
ordered.ShouldHaveTheSameElementsAs(doc1.Id, doc4.Id, doc3.Id, doc2.Id);
}
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/ValueTypeTests/linq_querying_with_value_types.cs#L31-L53' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_value_type_in_linq' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/ValueTypeTests/linq_querying_with_value_types.cs#L32-L54' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_value_type_in_linq' title='Start of snippet'>anchor</a></sup>
<a id='snippet-sample_using_value_type_in_linq-1'></a>
```cs
[Fact]
4 changes: 2 additions & 2 deletions docs/events/appending.md
Original file line number Diff line number Diff line change
@@ -138,7 +138,7 @@ session.Events.Append(id, joined, departed);

await session.SaveChangesAsync();
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/end_to_end_event_capture_and_fetching_the_stream_Tests.cs#L582-L591' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_append-events' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/end_to_end_event_capture_and_fetching_the_stream.cs#L582-L591' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_append-events' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

## Mandatory Stream Types <Badge type="tip" text="7.30" />
@@ -171,7 +171,7 @@ builder.Services.AddMarten(opts =>
opts.Events.UseMandatoryStreamTypeDeclaration = true;
});
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/mandatory_stream_type_behavior.cs#L117-L129' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_usemandatorystreamtypedeclaration' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/mandatory_stream_type_behavior.cs#L150-L162' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_usemandatorystreamtypedeclaration' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

This causes a couple side effects that **force stricter usage of Marten**:
2 changes: 1 addition & 1 deletion docs/events/index.md
Original file line number Diff line number Diff line change
@@ -47,7 +47,7 @@ var store2 = DocumentStore.For(_ =>
_.Events.AddEventType(typeof(MonsterSlayed));
});
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/using_the_schema_objects_Tests.cs#L33-L43' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_registering-event-types' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/schema_object_management.cs#L41-L51' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_registering-event-types' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

## Stream or Aggregate Types
9 changes: 4 additions & 5 deletions docs/events/optimizing.md
Original file line number Diff line number Diff line change
@@ -29,18 +29,17 @@ builder.Services.AddMarten(opts =>
opts.Events.AppendMode = EventAppendMode.Quick;

// Little more involved, but this can reduce the number
// of database queries necessary to process inline projections
// during command handling with some significant
// caveats
opts.Events.UseIdentityMapForInlineAggregates = true;
// of database queries necessary to process projections
// during CQRS command handling with certain workflows
opts.Events.UseIdentityMapForAggregates = true;

// 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;
});
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/Examples/Optimizations.cs#L31-L59' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_turn_on_optimizations_for_event_sourcing' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/Examples/Optimizations.cs#L31-L58' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_turn_on_optimizations_for_event_sourcing' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

The archived stream option is further described in the section on [Hot/Cold Storage Partitioning](/events/archiving.html#hot-cold-storage-partitioning).
8 changes: 8 additions & 0 deletions docs/events/projections/aggregate-projections.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,13 @@
# Aggregate Projections

::: tip
Definitely check out the content on [CQRS Command Handler Workflow for Capturing Events](/scenarios/command_handler_workflow)
and [Reading Aggregates](/events/projections/read-aggregates) to get the best possible performance and
development usability for aggregate projections with Marten. Also see the combination with [Wolverine](https://wolverinefx.net)
in its [Aggregate Handler Workflow](https://wolverinefx.net/guide/durability/marten/event-sourcing.html) for literally the
lowest code ceremony possible to use Marten within a CQRS architecture.
:::

_Aggregate Projections_ in Marten combine some sort of grouping of events and process them to create a single
aggregated document representing the state of those events. To jump into a simple example, here's a simple aggregated
view called `QuestParty` that creates an aggregated view of `MembersJoined`, `MembersDeparted`, and `QuestStarted` events related to a group of heroes traveling on a quest in your favorite fantasy novel:
8 changes: 4 additions & 4 deletions docs/events/projections/custom-aggregates.md
Original file line number Diff line number Diff line change
@@ -27,7 +27,7 @@ public class Increment
{
}
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/Aggregation/CustomProjectionTests.cs#L524-L542' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_custom_aggregate_events' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/Aggregation/CustomProjectionTests.cs#L655-L673' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_custom_aggregate_events' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

And a simple aggregate document type like this:
@@ -51,7 +51,7 @@ public class StartAndStopAggregate: ISoftDeleted
}
}
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/Aggregation/CustomProjectionTests.cs#L504-L522' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_startandstopaggregate' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/Aggregation/CustomProjectionTests.cs#L635-L653' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_startandstopaggregate' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

As you can see, `StartAndStopAggregate` as a `Guid` as its identity and is also [soft-deleted](/documents/deletes.html#soft-deletes) when stored by
@@ -126,7 +126,7 @@ public class StartAndStopProjection: CustomProjection<StartAndStopAggregate, Gui
}
}
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/Aggregation/CustomProjectionTests.cs#L544-L612' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_custom_aggregate_with_start_and_stop' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/Aggregation/CustomProjectionTests.cs#L675-L743' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_custom_aggregate_with_start_and_stop' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

## Custom Grouping
@@ -168,7 +168,7 @@ public class ExplicitCounter: CustomProjection<SimpleAggregate, Guid>
}
}
```
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/Projections/using_explicit_code_for_live_aggregation.cs#L40-L61' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_simple_explicit_code_for_live_aggregation' title='Start of snippet'>anchor</a></sup>
<sup><a href='https://github.com/JasperFx/marten/blob/master/src/EventSourcingTests/Projections/using_explicit_code_for_live_aggregation.cs#L77-L98' title='Snippet source file'>snippet source</a> | <a href='#snippet-sample_using_simple_explicit_code_for_live_aggregation' title='Start of snippet'>anchor</a></sup>
<!-- endSnippet -->

Note that this usage is valid for all possible projection lifecycles now (`Live`, `Inline`, and `Async`).
Loading