Filter received messages
This guide shows you how to set a subscribe filter expression on a PubNub client. The server then discards a non-matching message before it reaches that client.
- Set a filter expression when you create a client.
- Put a value the filter can read into the message payload or into
meta. - Exclude the messages your own client published.
- Sample a percentage of a high-volume stream.
Every call on this page needs an SDK instance initialized with your subscribe key, and the Stream Controller add-on enabled on your keyset in the Admin Portal. If you don't have a keyset yet, start with Set up your account. This page covers the calls that set an expression. For the expression language itself, the operators, data types, and precedence, refer to Subscribe filter expressions.
Set a filter expression
A subscribe filter is a property of the client, not of one subscription or channel, so it applies to every channel and channel group that client subscribes to. Set it before your first subscribe call.
- JavaScript
- Swift
- Java
- Kotlin
- Python
- C#
- PHP
- Objective-C
1const pubnub = new PubNub({
2 subscribeKey: 'mySubscribeKey',
3 userId: 'myUserId',
4});
5
6pubnub.setFilterExpression('meta.priority == "high"');
1let config = PubNubConfiguration(
2 subscribeKey: "mySubscribeKey",
3 userId: "myUserId",
4 filterExpression: "meta.priority == \"high\""
5)
6let pubnub = PubNub(configuration: config)
1PNConfiguration pnConfiguration = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey").build();
2pnConfiguration.setFilterExpression("meta.priority == \"high\"");
3
4PubNub pubnub = PubNub.create(pnConfiguration);
1val pnConfiguration = PNConfiguration.builder(UserId("myUserId"), "mySubscribeKey").build()
2pnConfiguration.filterExpression = "meta.priority == \"high\""
3
4val pubnub = PubNub.create(pnConfiguration)
1pnconfig = PNConfiguration()
2pnconfig.subscribe_key = "mySubscribeKey"
3pnconfig.user_id = "myUserId"
4pnconfig.filter_expression = 'meta.priority == "high"'
5
6pubnub = PubNub(pnconfig)
1PNConfiguration pnConfiguration = new PNConfiguration(new UserId("myUserId"));
2pnConfiguration.SubscribeKey = "mySubscribeKey";
3pnConfiguration.FilterExpression = "meta.priority == \"high\"";
4
5Pubnub pubnub = new Pubnub(pnConfiguration);
1$pnconfig = new PNConfiguration();
2$pnconfig->setSubscribeKey("mySubscribeKey");
3$pnconfig->setUserId("myUserId");
4$pnconfig->setFilterExpression('meta.priority == "high"');
5
6$pubnub = new PubNub($pnconfig);
1PNConfiguration *configuration = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
2 subscribeKey:@"mySubscribeKey"
3 userID:@"myUserId"];
4self.client = [PubNub clientWithConfiguration:configuration];
5self.client.filterExpression = @"meta.priority == \"high\"";
Whether you can change the expression again on a client that's already subscribing depends on the SDK. JavaScript's setFilterExpression() and Objective-C's filterExpression property both work on an already-created client and take effect on its next subscribe request. Java, Kotlin, PHP, and Swift fix the filter at configuration time. Their configuration becomes immutable once it creates a client, so changing the filter means building a new client with a new expression. Swift's legacy subscribe(filterOverride:) call is the one exception, overriding the filter for a single subscribe request. Check your SDK's configuration reference before assuming either behavior.
Make a value filterable
A filter expression can read only two places: the message payload, as data.*, and the metadata attached with meta at publish time, as meta.*. It can't read envelope fields such as the publisher's User ID, the channel name, the timetoken, or the message type. To filter on any of those, decide at publish time and put the value in meta or the payload yourself.
When message encryption is enabled, a subscribe filter cannot read data.*. meta.* remains unencrypted and filterable, so never put a secret in meta.
For the full syntax, every operator, and the data types each one accepts, refer to Subscribe filter expressions.
Exclude your own published messages
A client's own User ID isn't addressable in a filter expression, because it's an envelope field, not part of data.* or meta.*. Publish it into meta yourself, then filter it out:
1await pubnub.publish({
2 channel: 'updates',
3 message: { text: 'Hello world' },
4 meta: { publisher: pubnub.getUserId() },
5});
6
7pubnub.setFilterExpression(`meta.publisher != "${pubnub.getUserId()}"`);
Only the client that set this filter drops its own messages. Every other client subscribed to updates still receives them, because the filter is a property of the filtering client, not a rule attached to the message.
Sample a percentage of a stream
Modulo arithmetic on a numeric field keeps roughly one message in every N. That cuts a high-volume stream down before it reaches the client, instead of discarding the extra messages after they arrive:
meta.eventId % 10 == 0
This keeps about 10% of messages. The sample is only as even as eventId's distribution. A sequential counter gives you exactly one in ten. A hashed or random ID only approximates it. Publish the field you intend to sample on into meta or the payload the same way you would any other filterable value.
Related tasks
- Subscribe filter expressions. The full expression syntax, operators, data types, and precedence.
- Filter on the server. What a subscribe filter is, where it runs, and its design constraints.
- Send different message types. Attach the
metaa filter reads. - Receive messages. Create a subscription and register handlers on it.
- Subscribe. The subscribe model a filter narrows.