diff --git a/Directory.Build.props b/Directory.Build.props
index 5cd567c..0925be3 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -11,7 +11,7 @@
https://github.com/squidex/squidex
true
snupkg
- 6.30.0
+ 6.31.0
diff --git a/events/Squidex.Events.Mongo/FilterBuilder.cs b/events/Squidex.Events.Mongo/FilterBuilder.cs
index 3d11330..314dfb3 100644
--- a/events/Squidex.Events.Mongo/FilterBuilder.cs
+++ b/events/Squidex.Events.Mongo/FilterBuilder.cs
@@ -44,12 +44,22 @@ public static FilterDefinition ByStream(StreamFilter filter)
if (filter.Kind == StreamFilterKind.MatchStart)
{
- return builder.Or(filter.Prefixes.Select(p => builder.Regex(x => x.EventStream, $"^{p}")));
+ return builder.Or(filter.Prefixes.Select(p => Buildregex(p, builder)));
}
return builder.In(x => x.EventStream, filter.Prefixes);
}
+ private static FilterDefinition Buildregex(string prefix, FilterDefinitionBuilder builder)
+ {
+ if (prefix.StartsWith('%'))
+ {
+ prefix = $"([a-zA-Z0-9]+){prefix[1..]}";
+ }
+
+ return builder.Regex(x => x.EventStream, $"^{prefix}");
+ }
+
public static FilterDefinition>? ByChangeInStream(StreamFilter filter)
{
var builder = Builders>.Filter;
diff --git a/events/Squidex.Events.Tests/EventStoreTests.cs b/events/Squidex.Events.Tests/EventStoreTests.cs
index 6331022..8e4a917 100644
--- a/events/Squidex.Events.Tests/EventStoreTests.cs
+++ b/events/Squidex.Events.Tests/EventStoreTests.cs
@@ -417,11 +417,12 @@ public async Task Should_query_all_reverse_by_names(int commits, int count)
[InlineData(5, 30)]
[InlineData(5, 300)]
[InlineData(5, 3000)]
- public async Task Should_query_all_reverse_by_filter(int commits, int count)
+ public async Task Should_query_all_reverse_by_prefix(int commits, int count)
{
var sut = await CreateSutAsync();
- var streamName = $"test-{Guid.NewGuid()}-suffix";
+ var randomPart = Guid.NewGuid();
+ var streamName = $"test-{randomPart}-suffix";
var streamFilter = StreamFilter.Prefix(streamName[..^7], "invalid");
var eventsWritten = await AppendEventsAsync(sut, streamName, count, commits);
@@ -436,6 +437,30 @@ public async Task Should_query_all_reverse_by_filter(int commits, int count)
}
}
+ [Theory]
+ [InlineData(5, 30)]
+ [InlineData(5, 300)]
+ [InlineData(5, 3000)]
+ public async Task Should_query_all_reverse_by_wildcard_prefix(int commits, int count)
+ {
+ var sut = await CreateSutAsync();
+
+ var randomPart = Guid.NewGuid();
+ var streamName = $"test-{randomPart}-suffix";
+ var streamFilter = StreamFilter.Prefix($"%-{randomPart}", "invalid");
+
+ var eventsWritten = await AppendEventsAsync(sut, streamName, count, commits);
+ var eventsStored = eventsWritten.Select((x, i) => new StoredEvent(streamName, "Position", i, x)).ToArray();
+
+ for (var take = 0; take < count; take += count / 10)
+ {
+ var eventsExpected = eventsStored.Reverse().Take(take).ToArray();
+ var eventsQueried = await sut.QueryAllReverseAsync(streamFilter, default, take, ct).ToArrayAsync();
+
+ ShouldBeEquivalentTo(eventsQueried, eventsExpected);
+ }
+ }
+
[Theory]
[InlineData(5, 30)]
[InlineData(5, 300)]