# Server-side filtering
EventStoreDB allows you to filter the events whilst you subscribe to the $all
stream so that you only receive the events that you care about.
You can filter by event type or stream name using either a regular expression or a prefix. Server-side filtering is currently only available on the $all
stream.
TIP
Server-side filtering introduced as a simpler alternative to projections. Before creating a projection to get the events you care about you should first consider filtering.
# Filtering out system events
There are a number of events in EventStoreDB called system events. These are prefixed with a $
and under most circumstances you won't care about these. They can be filtered out by passing in a SubscriptionFilterOptions
when subscribing to the $all
stream.
await client.SubscribeToAllAsync(Position.Start,
(s, e, c) => {
Console.WriteLine(
$"{e.Event.EventType} @ {e.Event.Position.PreparePosition}");
return Task.CompletedTask;
},
filterOptions: new SubscriptionFilterOptions(
EventTypeFilter.ExcludeSystemEvents())
);
const excludeSystemEventsRegex = /^[^\$].*/;
const subscription = client
.subscribeToAll({
fromRevision: START,
filter: eventTypeFilter({ regex: excludeSystemEventsRegex }),
})
.on("data", function (resolvedEvent) {
console.log(
`Received event ${resolvedEvent.event.revision}@${resolvedEvent.event.streamId}`
);
});
// Make sure to add code blocks to your code group
TIP
$stats
events are no longer stored in EventStoreDB by default so there won't be as many $
events as before.
# Filtering by event type
If you only want to subscribe to events of a given type there are two options. You can either use a regular expression or a prefix.
# Filtering by prefix
If you want to filter by prefix pass in a SubscriptionFilterOptions
to the subscription with an EventTypeFilter.Prefix
.
var filter = new SubscriptionFilterOptions(
EventTypeFilter.Prefix("customer-"));
const prefixes = ["customer-"];
const filter = eventTypeFilter({ prefixes });
// Make sure to add code blocks to your code group
This will only subscribe to events with a type that begin with customer-
.
# Filtering by regular expression
If you want to subscribe to multiple event types then it might be better to provide a regular expression.
var filter = new SubscriptionFilterOptions(
EventTypeFilter.RegularExpression("^user|^company"));
const regex = /^user|^company/;
const filter = eventTypeFilter({ regex });
// Make sure to add code blocks to your code group
This will subscribe to any event that begins with user
or company
.
# Filtering by stream name
If you only want to subscribe to streams with a given there are two options. You can either use a regular expression or a prefix.
# Filtering by prefix
If you want to filter by prefix pass in a SubscriptionFilterOptions
to the subscription with an StreamFilter.Prefix
.
var filter = new SubscriptionFilterOptions(
StreamFilter.Prefix("user-"));
const prefixes = ["user-"];
const filter = streamNameFilter({ prefixes });
// Make sure to add code blocks to your code group
This will only subscribe to streams with a name that begin with user-
.
# Filtering by regular expression
If you want to subscribe to multiple streams then it might be better to provide a regular expression.
var filter = new SubscriptionFilterOptions(
StreamFilter.RegularExpression("^account|^savings"));
const regex = /^account|^savings/;
const filter = streamNameFilter({ regex });
// Make sure to add code blocks to your code group
This will subscribe to any stream with a name that begins with account
or savings
.
# Checkpointing
There is one thing to consider with server-side filtering, and that is when events that match your filter are few and far between. In this scenario, you might find yourself in the situation where EventStoreDB has searched through 1 million events, and the last thing you want to happen is for the server to get to event 900k and then have your client crash. It won't have been able to take a checkpoint and upon a restart, you'd have to go back to the beginning and start again.
In this case you can make use of an additional delegate that will be triggered every n number of events (32 by default).
To make use of it set up checkpointReached
on the SubscriptionFilterOptions
class.
var filter = new SubscriptionFilterOptions(
EventTypeFilter.ExcludeSystemEvents(),
checkpointReached: (s, p, c) =>
{
Console.WriteLine($"checkpoint taken at {p.PreparePosition}");
return Task.CompletedTask;
});
// TODO
// Make sure to add code blocks to your code group
This will be called every n
number of events. If you want to be specific about the number of events threshold you can also pass that as a parameter.
var filter = new SubscriptionFilterOptions(
EventTypeFilter.ExcludeSystemEvents(),
checkpointInterval: 1000,
checkpointReached: (s, p, c) =>
{
Console.WriteLine($"checkpoint taken at {p.PreparePosition}");
return Task.CompletedTask;
});
const excludeSystemEventsRegex = /^[^\$].*/;
const filter = eventTypeFilter({
checkpointIntervalMul: 1000,
regex: excludeSystemEventsRegex,
});
// Make sure to add code blocks to your code group
WARNING
This number will be called every n * 32
events.