Subscribe Filter Details
PubNub's subscribe filters provide comprehensive server-side message filtering capabilities, enabling sophisticated real-time message routing based on payload content, metadata, and complex business logic. Filters are applied before messages reach your client, dramatically reducing bandwidth and improving application performance.
Overview
Subscribe filters use a powerful expression language to evaluate messages against your criteria. Only messages that match your filter expressions are delivered to your subscribers, while non-matching messages are filtered out server-side.
Core benefits include:
- Real-time personalization - Each subscriber receives only relevant messages based on their preferences, location, permissions, or context without requiring separate channels
- Dynamic multi-tenancy - Single channel serves multiple user segments with different filtering rules, enabling scalable SaaS architectures without channel proliferation
- Intelligent event routing - Route messages based on complex business logic combining user roles, content types, geographic boundaries, and priority levels in real-time
- Scalable sampling & analytics - Filter high-volume data streams for analytics, monitoring, and sampling without overwhelming downstream systems or clients
Filter expression fundamentals
Use filters against two data sources: message payload (data.*
) and message metadata (meta.*
).
Data access
Subscribe filters can access two main data sources within each message:
Prefix | Data Source | Example Fields | Access Pattern |
---|---|---|---|
data.* | Message payload | data.text , data.type , data.score | Any field in published message content |
meta.* | Message metadata | meta.priority , meta.region , meta.level | Metadata attached via meta parameter |
Supported operators
Category | Operators | Description | Examples |
---|---|---|---|
Comparison | == , != , > , < , >= , <= | Standard comparisons | meta.level > 5 , data.score >= 80 |
Pattern | LIKE , CONTAINS | Wildcard and substring matching | meta.category LIKE "news*" , data.text CONTAINS "urgent" |
Logical | && , || , ! | Boolean logic operators | (meta.priority == "high") && (data.type == "alert") |
Arithmetic | + , - , * , / , % | Mathematical operations | meta.userId % 10 == 0 , data.score > (meta.threshold + 5) |
Access | [index] , ["key"] | Array and object access | meta.tags[0] == "urgent" , meta.user["role"] == "admin" |
Basic filtering
Use simple expressions to match fields in data.*
or meta.*
; start with strings, then numbers.
String filtering
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Exact string matching
pubnub.setFilterExpression('meta.priority == "high"');
pubnub.setFilterExpression('data.category != "test"');
// Multiple string conditions
pubnub.setFilterExpression('meta.region == "San Francisco" && data.type == "alert"');
// String filter configuration
let config = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "meta.priority == \"high\""
)
let pubnub = PubNub(configuration: config)
// Multiple string conditions
let complexConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "meta.region == \"San Francisco\" && data.type == \"alert\""
show all 16 lines// Set string filters via configuration
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"meta.priority == \"high\"";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Complex string filtering
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"meta.region == \"San Francisco\" && data.type == \"alert\"";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// String filter configuration
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("meta.priority == \"high\"");
PubNub pubnub = PubNub.create(configBuilder.build());
// Multiple string conditions
PNConfiguration.Builder complexBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
complexBuilder.publishKey("myPublishKey");
complexBuilder.setFilterExpression("meta.region == \"San Francisco\" && data.type == \"alert\"");
PubNub complexPubNub = PubNub.create(complexBuilder.build());
// Set string filters via configuration
pnconfig.FilterExpression = "meta.priority == \"high\"";
pnconfig.FilterExpression = "data.category != \"test\"";
// Complex string filtering
pnconfig.FilterExpression = "meta.region == \"San Francisco\" && data.type == \"alert\"";
# Set string filters via configuration
pnconfig.filter_expression = 'meta.priority == "high"'
pnconfig.filter_expression = 'data.category != "test"'
# Multiple string conditions
pnconfig.filter_expression = 'meta.region == "San Francisco" && data.type == "alert"'
Numeric filtering
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Numeric comparisons
pubnub.setFilterExpression('meta.level > 10');
pubnub.setFilterExpression('data.score >= 80');
pubnub.setFilterExpression('meta.priority <= 3');
// Range filtering
pubnub.setFilterExpression('meta.score >= 80 && meta.score <= 100');
// Calculated thresholds
pubnub.setFilterExpression('data.usage > (data.limit * 0.8)');
// Numeric filter configuration
let config = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "meta.level > 10"
)
let pubnub = PubNub(configuration: config)
// Range filtering example
let rangeConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "meta.score >= 80 && meta.score <= 100"
show all 16 lines// Numeric comparisons via configuration
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"meta.level > 10";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Range filtering
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"meta.score >= 80 && meta.score <= 100";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Numeric filter configuration
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("meta.level > 10");
PubNub pubnub = PubNub.create(configBuilder.build());
// Range filtering
PNConfiguration.Builder rangeBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
rangeBuilder.publishKey("myPublishKey");
rangeBuilder.setFilterExpression("meta.score >= 80 && meta.score <= 100");
PubNub rangePubNub = PubNub.create(rangeBuilder.build());
// Numeric comparisons
pnconfig.FilterExpression = "meta.level > 10";
pnconfig.FilterExpression = "data.score >= 80";
pnconfig.FilterExpression = "meta.priority <= 3";
// Range filtering
pnconfig.FilterExpression = "meta.score >= 80 && meta.score <= 100";
# Numeric comparisons
pnconfig.filter_expression = 'meta.level > 10'
pnconfig.filter_expression = 'data.score >= 80'
pnconfig.filter_expression = 'meta.priority <= 3'
# Range filtering
pnconfig.filter_expression = 'meta.score >= 80 && meta.score <= 100'
Pattern matching
Use LIKE
for wildcard matches and CONTAINS
for substring searches on fields in data.*
and meta.*
.
LIKE operator (wildcard matching)
The LIKE
operator provides powerful pattern matching with wildcard support.
Wildcard rules include:
- Use
*
for wildcard matching *
can be at start, end, or both:"*middle*"
,"prefix*"
,"*suffix"
- Escape literal asterisks with backslash:
"literal\*"
- Pattern matching is case-insensitive
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Wildcard patterns
pubnub.setFilterExpression('meta.category LIKE "news*"'); // Starts with "news"
pubnub.setFilterExpression('data.title LIKE "*breaking*"'); // Contains "breaking"
pubnub.setFilterExpression('meta.version LIKE "2.1*"'); // Version prefix
// Complex pattern combinations
pubnub.setFilterExpression('data.subject LIKE "*[URGENT]*" && data.body CONTAINS "maintenance"');
// Wildcard pattern configuration
let config = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "meta.category LIKE \"news*\""
)
let pubnub = PubNub(configuration: config)
// Additional pattern examples
let patternConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "data.title LIKE \"*breaking*\""
show all 16 lines// Wildcard patterns via configuration
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"meta.category LIKE \"news*\"";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Multiple pattern examples
config.filterExpression = @"data.title LIKE \"*breaking*\"";
config.filterExpression = @"meta.version LIKE \"2.1*\"";
// Wildcard pattern configuration
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("meta.category LIKE \"news*\"");
PubNub pubnub = PubNub.create(configBuilder.build());
// Additional pattern examples
configBuilder.setFilterExpression("data.title LIKE \"*breaking*\"");
configBuilder.setFilterExpression("meta.version LIKE \"2.1*\"");
// Wildcard patterns
pnconfig.FilterExpression = "meta.category LIKE \"news*\"";
pnconfig.FilterExpression = "data.title LIKE \"*breaking*\"";
pnconfig.FilterExpression = "meta.version LIKE \"2.1*\"";
# Wildcard patterns
pnconfig.filter_expression = 'meta.category LIKE "news*"'
pnconfig.filter_expression = 'data.title LIKE "*breaking*"'
pnconfig.filter_expression = 'meta.version LIKE "2.1*"'
CONTAINS operator (substring search)
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Substring search
pubnub.setFilterExpression('meta.tags CONTAINS "urgent"');
pubnub.setFilterExpression('data.description CONTAINS "error"');
// Multiple substring conditions
pubnub.setFilterExpression('data.text CONTAINS "urgent" && meta.category CONTAINS "alert"');
// Substring search configuration
let config = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "meta.tags CONTAINS \"urgent\""
)
let pubnub = PubNub(configuration: config)
// Additional CONTAINS example
let containsConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "data.description CONTAINS \"error\""
show all 16 lines// Substring search via configuration
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"meta.tags CONTAINS \"urgent\"";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Additional CONTAINS examples
config.filterExpression = @"data.description CONTAINS \"error\"";
// Substring search configuration
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("meta.tags CONTAINS \"urgent\"");
PubNub pubnub = PubNub.create(configBuilder.build());
// Additional CONTAINS examples
configBuilder.setFilterExpression("data.description CONTAINS \"error\"");
// Substring search
pnconfig.FilterExpression = "meta.tags CONTAINS \"urgent\"";
pnconfig.FilterExpression = "data.description CONTAINS \"error\"";
# Substring search
pnconfig.filter_expression = 'meta.tags CONTAINS "urgent"'
pnconfig.filter_expression = 'data.description CONTAINS "error"'
Advanced filtering
Use these patterns to access arrays and objects, perform arithmetic, and handle booleans in subscribe filter expressions.
Array and object access
Subscribe filters support direct access to array elements and object properties within both payload and metadata.
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Array element access
pubnub.setFilterExpression('meta.tags[0] == "urgent"'); // First element
pubnub.setFilterExpression('data.recipients[1] LIKE "*@company.com"'); // Second element
// Object property access
pubnub.setFilterExpression('meta.user["role"] == "admin"'); // Object key access
pubnub.setFilterExpression('data.config["enabled"] == "true"'); // Nested object
// Combined array and object access
pubnub.setFilterExpression('meta.permissions[0] == "read" && data.user["department"] == "engineering"');
// Array and object access configuration
let config = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "meta.tags[0] == \"urgent\""
)
let pubnub = PubNub(configuration: config)
// Object access examples
let objectConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "meta.user[\"role\"] == \"admin\""
show all 16 lines// Array and object access via configuration
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"meta.tags[0] == \"urgent\"";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Object access examples
config.filterExpression = @"meta.user[\"role\"] == \"admin\"";
config.filterExpression = @"data.config[\"enabled\"] == \"true\"";
// Array and object access configuration
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("meta.tags[0] == \"urgent\"");
PubNub pubnub = PubNub.create(configBuilder.build());
// Object access examples
configBuilder.setFilterExpression("meta.user[\"role\"] == \"admin\"");
configBuilder.setFilterExpression("data.config[\"enabled\"] == \"true\"");
// Array and object access
pnconfig.FilterExpression = "meta.tags[0] == \"urgent\"";
pnconfig.FilterExpression = "meta.user[\"role\"] == \"admin\"";
pnconfig.FilterExpression = "data.config[\"enabled\"] == \"true\"";
# Array and object access
pnconfig.filter_expression = 'meta.tags[0] == "urgent"'
pnconfig.filter_expression = 'meta.user["role"] == "admin"'
pnconfig.filter_expression = 'data.config["enabled"] == "true"'
Single-level access only
Array and object access supports one level of indexing (meta.array[0]
, meta.object["key"]
). Multi-level chained access (meta.data["array"][0]
) is not supported.
Arithmetic operations
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Modulo operations for sampling
pubnub.setFilterExpression('meta.userId % 10 == 0'); // 10% sampling
pubnub.setFilterExpression('meta.messageId % 100 == 0'); // 1% sampling
// Arithmetic calculations in filters
pubnub.setFilterExpression('data.score > (meta.baseline + 10)');
pubnub.setFilterExpression('meta.attempts < (meta.maxRetries - 1)');
// Complex arithmetic expressions
pubnub.setFilterExpression('(data.total - data.used) > (data.limit * 0.2)');
// Modulo operations configuration
let config = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "meta.userId % 10 == 0"
)
let pubnub = PubNub(configuration: config)
// Arithmetic calculations example
let arithmeticConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "data.score > (meta.baseline + 10)"
show all 16 lines// Modulo operations via configuration
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"meta.userId % 10 == 0";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Arithmetic calculations
config.filterExpression = @"meta.messageId % 100 == 0";
config.filterExpression = @"data.score > (meta.baseline + 10)";
// Modulo operations configuration
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("meta.userId % 10 == 0");
PubNub pubnub = PubNub.create(configBuilder.build());
// Arithmetic calculations
configBuilder.setFilterExpression("meta.messageId % 100 == 0");
configBuilder.setFilterExpression("data.score > (meta.baseline + 10)");
// Modulo operations
pnconfig.FilterExpression = "meta.userId % 10 == 0";
pnconfig.FilterExpression = "meta.messageId % 100 == 0";
// Arithmetic calculations
pnconfig.FilterExpression = "data.score > (meta.baseline + 10)";
# Modulo operations
pnconfig.filter_expression = 'meta.userId % 10 == 0'
pnconfig.filter_expression = 'meta.messageId % 100 == 0'
# Arithmetic calculations
pnconfig.filter_expression = 'data.score > (meta.baseline + 10)'
Boolean value handling
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Boolean values as strings (recommended approach)
pubnub.setFilterExpression('meta.enabled == "true"');
pubnub.setFilterExpression('meta.active == "false"');
pubnub.setFilterExpression('meta.verified != "false"');
// Numeric boolean flags (alternative)
pubnub.setFilterExpression('meta.isActive == 1'); // 1 for true
pubnub.setFilterExpression('meta.isDisabled == 0'); // 0 for false
// Boolean string configuration
let config = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "meta.enabled == \"true\""
)
let pubnub = PubNub(configuration: config)
// Numeric boolean example
let boolConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "meta.isActive == 1"
show all 16 lines// Boolean as string via configuration
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"meta.enabled == \"true\"";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Numeric boolean examples
config.filterExpression = @"meta.active == \"false\"";
config.filterExpression = @"meta.isActive == 1";
// Boolean string configuration
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("meta.enabled == \"true\"");
PubNub pubnub = PubNub.create(configBuilder.build());
// Numeric boolean examples
configBuilder.setFilterExpression("meta.active == \"false\"");
configBuilder.setFilterExpression("meta.isActive == 1");
// Boolean as string
pnconfig.FilterExpression = "meta.enabled == \"true\"";
pnconfig.FilterExpression = "meta.active == \"false\"";
// Numeric boolean
pnconfig.FilterExpression = "meta.isActive == 1";
# Boolean as string
pnconfig.filter_expression = 'meta.enabled == "true"'
pnconfig.filter_expression = 'meta.active == "false"'
# Numeric boolean
pnconfig.filter_expression = 'meta.isActive == 1'
Boolean literal limitation
Do not use boolean literals (true
/false
) in filter expressions. Always use string comparison ("true"
/"false"
) or numeric flags (1/0). JSON boolean values are stored as strings in the filtering system.
Complex expressions
Build complex filters by combining conditions (AND/OR), nesting expressions, and using parentheses for clarity.
Compound logic
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// AND expressions
pubnub.setFilterExpression('(meta.priority == "high") && (data.type == "alert")');
pubnub.setFilterExpression('meta.level > 5 && meta.region == "San Francisco"');
// OR expressions
pubnub.setFilterExpression('(meta.priority == "high") || (meta.priority == "critical")');
pubnub.setFilterExpression('data.category == "news" || data.category == "sports"');
// Nested logical expressions
pubnub.setFilterExpression('((meta.priority == "high") || (meta.priority == "critical")) && (data.score > 80)');
// Cross-field filtering
pubnub.setFilterExpression('(meta.userRole == "admin") && (data.action == "delete") && (data.target["type"] == "production")');
// Compound expressions configuration
let config = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "(meta.priority == \"high\") && (data.type == \"alert\")"
)
let pubnub = PubNub(configuration: config)
// Complex nested expressions
let complexConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "((meta.priority == \"high\") || (meta.priority == \"critical\")) && (data.score > 80)"
show all 16 lines// Compound expressions via configuration
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"(meta.priority == \"high\") && (data.type == \"alert\")";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Additional compound examples
config.filterExpression = @"(meta.priority == \"high\") || (meta.priority == \"critical\")";
config.filterExpression = @"((meta.priority == \"high\") || (meta.priority == \"critical\")) && (data.score > 80)";
// Compound expressions configuration
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("(meta.priority == \"high\") && (data.type == \"alert\")");
PubNub pubnub = PubNub.create(configBuilder.build());
// Additional compound examples
configBuilder.setFilterExpression("(meta.priority == \"high\") || (meta.priority == \"critical\")");
configBuilder.setFilterExpression("((meta.priority == \"high\") || (meta.priority == \"critical\")) && (data.score > 80)");
// Compound expressions
pnconfig.FilterExpression = "(meta.priority == \"high\") && (data.type == \"alert\")";
pnconfig.FilterExpression = "(meta.priority == \"high\") || (meta.priority == \"critical\")";
pnconfig.FilterExpression = "((meta.priority == \"high\") || (meta.priority == \"critical\")) && (data.score > 80)";
# Compound expressions
pnconfig.filter_expression = '(meta.priority == "high") && (data.type == "alert")'
pnconfig.filter_expression = '(meta.priority == "high") || (meta.priority == "critical")'
pnconfig.filter_expression = '((meta.priority == "high") || (meta.priority == "critical")) && (data.score > 80)'
Operator precedence
Expressions are evaluated according to standard mathematical precedence:
- Parentheses:
()
- Unary operators:
!
(logical NOT),~
(bitwise NOT) - Arithmetic:
*
,/
,%
(left-to-right) - Arithmetic:
+
,-
(left-to-right) - Comparison:
==
,!=
,<
,>
,<=
,>=
,LIKE
,CONTAINS
- Logical AND:
&&
- Logical OR:
||
Parentheses for clarity
Use parentheses to make precedence explicit in complex expressions.
Real-world applications
Use these examples to apply subscribe filters in chat, geolocation, IoT, and trading scenarios.
Chat application filtering
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Moderator message filtering
// This filter ensures only messages from moderators or admins with non-empty text are received,
// useful for administrative channels where only staff communications should be visible.
pubnub.setFilterExpression('(meta.user["role"] == "moderator" || meta.user["role"] == "admin") && data.text != ""');
// Direct message targeting
// This filter delivers messages only to users who are participants in a specific conversation,
// ensuring private messages reach only the intended recipients.
pubnub.setFilterExpression('meta.conversation["participants"] CONTAINS "' + currentUserId + '" && data.type == "direct_message"');
// Block list filtering
// This filter blocks messages from multiple specific users that have been blocked by the current user,
// providing a comprehensive user blocking mechanism for chat applications.
pubnub.setFilterExpression('meta.publisher != "user123" && meta.publisher != "user456" && meta.publisher != "user789" && meta.publisher != "user101" && meta.publisher != "user202" && meta.publisher != "user303" && meta.publisher != "user404" && meta.publisher != "user505" && meta.publisher != "user606" && meta.publisher != "user707"');
// Moderator message filtering
// This filter ensures only messages from moderators or admins with non-empty text are received,
// useful for administrative channels where only staff communications should be visible.
let config = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "(meta.user[\"role\"] == \"moderator\" || meta.user[\"role\"] == \"admin\") && data.text != \"\""
)
// Direct message targeting
// This filter delivers messages only to users who are participants in a specific conversation,
// ensuring private messages reach only the intended recipients.
let config = PubNubConfiguration(
publishKey: "myPublishKey",
show all 30 lines// Moderator message filtering
// This filter ensures only messages from moderators or admins with non-empty text are received,
// useful for administrative channels where only staff communications should be visible.
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"(meta.user[\"role\"] == \"moderator\" || meta.user[\"role\"] == \"admin\") && data.text != \"\"";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Direct message targeting
// This filter delivers messages only to users who are participants in a specific conversation,
// ensuring private messages reach only the intended recipients.
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
show all 27 lines// Moderator message filtering
// This filter ensures only messages from moderators or admins with non-empty text are received,
// useful for administrative channels where only staff communications should be visible.
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("(meta.user[\"role\"] == \"moderator\" || meta.user[\"role\"] == \"admin\") && data.text != \"\"");
PubNub pubnub = PubNub.create(configBuilder.build());
// Direct message targeting
// This filter delivers messages only to users who are participants in a specific conversation,
// ensuring private messages reach only the intended recipients.
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("meta.conversation[\"participants\"] CONTAINS \"" + currentUserId + "\" && data.type == \"direct_message\"");
PubNub pubnub = PubNub.create(configBuilder.build());
show all 24 lines// Moderator message filtering
// This filter ensures only messages from moderators or admins with non-empty text are received,
// useful for administrative channels where only staff communications should be visible.
pnconfig.FilterExpression = "(meta.user[\"role\"] == \"moderator\" || meta.user[\"role\"] == \"admin\") && data.text != \"\"";
// Direct message targeting
// This filter delivers messages only to users who are participants in a specific conversation,
// ensuring private messages reach only the intended recipients.
pnconfig.FilterExpression = $"meta.conversation[\"participants\"] CONTAINS \"{currentUserId}\" && data.type == \"direct_message\"";
// Block list filtering
// This filter blocks messages from multiple specific users that have been blocked by the current user,
// providing a comprehensive user blocking mechanism for chat applications.
pnconfig.FilterExpression = "meta.publisher != \"user123\" && meta.publisher != \"user456\" && meta.publisher != \"user789\" && meta.publisher != \"user101\" && meta.publisher != \"user202\" && meta.publisher != \"user303\" && meta.publisher != \"user404\" && meta.publisher != \"user505\" && meta.publisher != \"user606\" && meta.publisher != \"user707\"";
# Moderator message filtering
# This filter ensures only messages from moderators or admins with non-empty text are received,
# useful for administrative channels where only staff communications should be visible.
pnconfig.filter_expression = '(meta.user["role"] == "moderator" || meta.user["role"] == "admin") && data.text != ""'
# Direct message targeting
# This filter delivers messages only to users who are participants in a specific conversation,
# ensuring private messages reach only the intended recipients.
pnconfig.filter_expression = f'meta.conversation["participants"] CONTAINS "{current_user_id}" && data.type == "direct_message"'
# Block list filtering
# This filter blocks messages from multiple specific users that have been blocked by the current user,
# providing a comprehensive user blocking mechanism for chat applications.
pnconfig.filter_expression = 'meta.publisher != "user123" && meta.publisher != "user456" && meta.publisher != "user789" && meta.publisher != "user101" && meta.publisher != "user202" && meta.publisher != "user303" && meta.publisher != "user404" && meta.publisher != "user505" && meta.publisher != "user606" && meta.publisher != "user707"'
Geolocation filtering
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Geo-fence filtering (100m rectangular boundary)
// This filter creates a rectangular boundary around a specific location, useful for location-based
// notifications like nearby restaurant deals or local event announcements.
pubnub.setFilterExpression('(data.location["lat"] >= 37.7849 && data.location["lat"] <= 37.7869) && (data.location["lng"] >= -122.4094 && data.location["lng"] <= -122.4074)');
// Neighborhood-level filtering
// This filter targets messages to specific neighborhoods or districts, ideal for community apps,
// local news, or area-specific services combining geographic boundaries with content type filtering.
pubnub.setFilterExpression('meta.address["neighborhood"] LIKE "*mission*" && data.type == "local_event"');
// Emergency services - nearby incidents
// This filter delivers high-priority emergency alerts to users in specific geographic areas,
// essential for emergency response systems and public safety notifications.
pubnub.setFilterExpression('meta.emergency["priority"] >= 3 && data.location["zipcode"] == "94110" && meta.services CONTAINS "fire"');
// Geo-fence filtering (100m rectangular boundary)
// This filter creates a rectangular boundary around a specific location, useful for location-based
// notifications like nearby restaurant deals or local event announcements.
let geoConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "(data.location[\"lat\"] >= 37.7849 && data.location[\"lat\"] <= 37.7869) && (data.location[\"lng\"] >= -122.4094 && data.location[\"lng\"] <= -122.4074)"
)
// Neighborhood-level filtering
// This filter targets messages to specific neighborhoods or districts, ideal for community apps,
// local news, or area-specific services combining geographic boundaries with content type filtering.
let neighborhoodConfig = PubNubConfiguration(
publishKey: "myPublishKey",
show all 29 lines// Geo-fence filtering (100m rectangular boundary)
// This filter creates a rectangular boundary around a specific location, useful for location-based
// notifications like nearby restaurant deals or local event announcements.
PNConfiguration *geoConfig = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
geoConfig.uuid = @"myUserId";
geoConfig.filterExpression = @"(data.location[\"lat\"] >= 37.7849 && data.location[\"lat\"] <= 37.7869) && (data.location[\"lng\"] >= -122.4094 && data.location[\"lng\"] <= -122.4074)";
PubNub *geoPubNub = [PubNub clientWithConfiguration:geoConfig];
// Neighborhood-level filtering
// This filter targets messages to specific neighborhoods or districts, ideal for community apps,
// local news, or area-specific services combining geographic boundaries with content type filtering.
PNConfiguration *neighborhoodConfig = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
neighborhoodConfig.uuid = @"myUserId";
show all 26 lines// Geo-fence filtering (100m rectangular boundary)
// This filter creates a rectangular boundary around a specific location, useful for location-based
// notifications like nearby restaurant deals or local event announcements.
PNConfiguration.Builder geoBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
geoBuilder.publishKey("myPublishKey");
geoBuilder.setFilterExpression("(data.location[\"lat\"] >= 37.7849 && data.location[\"lat\"] <= 37.7869) && (data.location[\"lng\"] >= -122.4094 && data.location[\"lng\"] <= -122.4074)");
PubNub geoPubNub = PubNub.create(geoBuilder.build());
// Neighborhood-level filtering
// This filter targets messages to specific neighborhoods or districts, ideal for community apps,
// local news, or area-specific services combining geographic boundaries with content type filtering.
PNConfiguration.Builder neighborhoodBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
neighborhoodBuilder.publishKey("myPublishKey");
neighborhoodBuilder.setFilterExpression("meta.address[\"neighborhood\"] LIKE \"*mission*\" && data.type == \"local_event\"");
PubNub neighborhoodPubNub = PubNub.create(neighborhoodBuilder.build());
show all 23 lines// Geo-fence filtering (100m rectangular boundary)
// This filter creates a rectangular boundary around a specific location, useful for location-based
// notifications like nearby restaurant deals or local event announcements.
PNConfiguration geoConfig = new PNConfiguration(new UserId("myUserId"));
geoConfig.SubscribeKey = "mySubscribeKey";
geoConfig.PublishKey = "myPublishKey";
geoConfig.FilterExpression = "(data.location[\"lat\"] >= 37.7849 && data.location[\"lat\"] <= 37.7869) && (data.location[\"lng\"] >= -122.4094 && data.location[\"lng\"] <= -122.4074)";
Pubnub geoPubNub = new Pubnub(geoConfig);
// Neighborhood-level filtering
// This filter targets messages to specific neighborhoods or districts, ideal for community apps,
// local news, or area-specific services combining geographic boundaries with content type filtering.
PNConfiguration neighborhoodConfig = new PNConfiguration(new UserId("myUserId"));
neighborhoodConfig.SubscribeKey = "mySubscribeKey";
neighborhoodConfig.PublishKey = "myPublishKey";
show all 26 lines# Geo-fence filtering (100m rectangular boundary)
# This filter creates a rectangular boundary around a specific location, useful for location-based
# notifications like nearby restaurant deals or local event announcements.
geo_config = PNConfiguration()
geo_config.publish_key = "myPublishKey"
geo_config.subscribe_key = "mySubscribeKey"
geo_config.user_id = "myUserId"
geo_config.filter_expression = '(data.location["lat"] >= 37.7849 && data.location["lat"] <= 37.7869) && (data.location["lng"] >= -122.4094 && data.location["lng"] <= -122.4074)'
geo_pubnub = PubNub(geo_config)
# Neighborhood-level filtering
# This filter targets messages to specific neighborhoods or districts, ideal for community apps,
# local news, or area-specific services combining geographic boundaries with content type filtering.
neighborhood_config = PNConfiguration()
neighborhood_config.publish_key = "myPublishKey"
show all 29 linesIoT data stream filtering
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Sensor data filtering
// This filter monitors specific sensor types and triggers alerts when values exceed predefined thresholds,
// essential for environmental monitoring and automated alert systems in smart buildings or industrial facilities.
pubnub.setFilterExpression('data.sensor["type"] == "temperature" && data.value > meta.thresholds["high"]');
// Device health monitoring
// This filter identifies devices that need attention by monitoring battery levels and critical errors,
// enabling proactive maintenance and preventing device failures in IoT deployments.
pubnub.setFilterExpression('meta.device["status"] != "maintenance" && (data.battery < 20 || data.errors[0] CONTAINS "critical")');
// Time-based sampling
// This filter collects periodic reports from a subset of devices to reduce data volume while maintaining visibility,
// useful for large-scale IoT deployments where continuous monitoring of all devices would be overwhelming.
pubnub.setFilterExpression('meta.deviceId % 60 == 0 && data.timestamp LIKE "*:00:*"'); // Hourly reports
// Sensor data filtering
// This filter monitors specific sensor types and triggers alerts when values exceed predefined thresholds,
// essential for environmental monitoring and automated alert systems in smart buildings or industrial facilities.
let sensorConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "data.sensor[\"type\"] == \"temperature\" && data.value > meta.thresholds[\"high\"]"
)
let sensorPubNub = PubNub(configuration: sensorConfig)
// Device health monitoring
// This filter identifies devices that need attention by monitoring battery levels and critical errors,
// enabling proactive maintenance and preventing device failures in IoT deployments.
let deviceConfig = PubNubConfiguration(
show all 31 lines// Sensor data filtering
// This filter monitors specific sensor types and triggers alerts when values exceed predefined thresholds,
// essential for environmental monitoring and automated alert systems in smart buildings or industrial facilities.
PNConfiguration *sensorConfig = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
sensorConfig.uuid = @"myUserId";
sensorConfig.filterExpression = @"data.sensor[\"type\"] == \"temperature\" && data.value > meta.thresholds[\"high\"]";
PubNub *sensorPubNub = [PubNub clientWithConfiguration:sensorConfig];
// Device health monitoring
// This filter identifies devices that need attention by monitoring battery levels and critical errors,
// enabling proactive maintenance and preventing device failures in IoT deployments.
PNConfiguration *deviceConfig = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
deviceConfig.uuid = @"myUserId";
show all 26 lines// Sensor data filtering
// This filter monitors specific sensor types and triggers alerts when values exceed predefined thresholds,
// essential for environmental monitoring and automated alert systems in smart buildings or industrial facilities.
PNConfiguration.Builder sensorBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
sensorBuilder.publishKey("myPublishKey");
sensorBuilder.setFilterExpression("data.sensor[\"type\"] == \"temperature\" && data.value > meta.thresholds[\"high\"]");
PubNub sensorPubNub = PubNub.create(sensorBuilder.build());
// Device health monitoring
// This filter identifies devices that need attention by monitoring battery levels and critical errors,
// enabling proactive maintenance and preventing device failures in IoT deployments.
PNConfiguration.Builder deviceBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
deviceBuilder.publishKey("myPublishKey");
deviceBuilder.setFilterExpression("meta.device[\"status\"] != \"maintenance\" && (data.battery < 20 || data.errors[0] CONTAINS \"critical\")");
PubNub devicePubNub = PubNub.create(deviceBuilder.build());
show all 23 lines// Sensor data filtering
// This filter monitors specific sensor types and triggers alerts when values exceed predefined thresholds,
// essential for environmental monitoring and automated alert systems in smart buildings or industrial facilities.
PNConfiguration sensorConfig = new PNConfiguration(new UserId("myUserId"));
sensorConfig.SubscribeKey = "mySubscribeKey";
sensorConfig.PublishKey = "myPublishKey";
sensorConfig.FilterExpression = "data.sensor[\"type\"] == \"temperature\" && data.value > meta.thresholds[\"high\"]";
Pubnub sensorPubNub = new Pubnub(sensorConfig);
// Device health monitoring
// This filter identifies devices that need attention by monitoring battery levels and critical errors,
// enabling proactive maintenance and preventing device failures in IoT deployments.
PNConfiguration deviceConfig = new PNConfiguration(new UserId("myUserId"));
deviceConfig.SubscribeKey = "mySubscribeKey";
deviceConfig.PublishKey = "myPublishKey";
show all 26 lines# Sensor data filtering
# This filter monitors specific sensor types and triggers alerts when values exceed predefined thresholds,
# essential for environmental monitoring and automated alert systems in smart buildings or industrial facilities.
sensor_config = PNConfiguration()
sensor_config.publish_key = "myPublishKey"
sensor_config.subscribe_key = "mySubscribeKey"
sensor_config.user_id = "myUserId"
sensor_config.filter_expression = 'data.sensor["type"] == "temperature" && data.value > meta.thresholds["high"]'
sensor_pubnub = PubNub(sensor_config)
# Device health monitoring
# This filter identifies devices that need attention by monitoring battery levels and critical errors,
# enabling proactive maintenance and preventing device failures in IoT deployments.
device_config = PNConfiguration()
device_config.publish_key = "myPublishKey"
show all 29 linesFinancial trading filters
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Trading signal filtering
// This filter delivers cryptocurrency price alerts only when prices exceed user-defined thresholds,
// enabling personalized trading notifications while filtering out irrelevant market movements.
pubnub.setFilterExpression('data.symbol LIKE "CRYPTO*" && data.price > meta.user["minPrice"]');
// Risk management
// This filter enforces trading limits and compliance rules by monitoring position sizes and account restrictions,
// providing automated risk controls to prevent unauthorized or excessive trading activity.
pubnub.setFilterExpression('data.position["size"] <= meta.limits["maxPosition"] && !(meta.restrictions CONTAINS "dayTrading")');
// Market event filtering
// This filter identifies significant market movements by analyzing trade volume and price changes,
// delivering alerts only for high-impact events that meet minimum transaction value and volatility criteria.
pubnub.setFilterExpression('(data.volume * data.price) > meta.filters["minValue"] && data.changePercent > 5');
// Trading signal filtering
// This filter delivers cryptocurrency price alerts only when prices exceed user-defined thresholds,
// enabling personalized trading notifications while filtering out irrelevant market movements.
let tradingConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
filterExpression: "data.symbol LIKE \"CRYPTO*\" && data.price > meta.user[\"minPrice\"]"
)
let tradingPubNub = PubNub(configuration: tradingConfig)
// Risk management
// This filter enforces trading limits and compliance rules by monitoring position sizes and account restrictions,
// providing automated risk controls to prevent unauthorized or excessive trading activity.
let riskConfig = PubNubConfiguration(
show all 31 lines// Trading signal filtering
// This filter delivers cryptocurrency price alerts only when prices exceed user-defined thresholds,
// enabling personalized trading notifications while filtering out irrelevant market movements.
PNConfiguration *tradingConfig = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
tradingConfig.uuid = @"myUserId";
tradingConfig.filterExpression = @"data.symbol LIKE \"CRYPTO*\" && data.price > meta.user[\"minPrice\"]";
PubNub *tradingPubNub = [PubNub clientWithConfiguration:tradingConfig];
// Risk management
// This filter enforces trading limits and compliance rules by monitoring position sizes and account restrictions,
// providing automated risk controls to prevent unauthorized or excessive trading activity.
PNConfiguration *riskConfig = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
riskConfig.uuid = @"myUserId";
show all 26 lines// Trading signal filtering
// This filter delivers cryptocurrency price alerts only when prices exceed user-defined thresholds,
// enabling personalized trading notifications while filtering out irrelevant market movements.
PNConfiguration.Builder tradingBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
tradingBuilder.publishKey("myPublishKey");
tradingBuilder.setFilterExpression("data.symbol LIKE \"CRYPTO*\" && data.price > meta.user[\"minPrice\"]");
PubNub tradingPubNub = PubNub.create(tradingBuilder.build());
// Risk management
// This filter enforces trading limits and compliance rules by monitoring position sizes and account restrictions,
// providing automated risk controls to prevent unauthorized or excessive trading activity.
PNConfiguration.Builder riskBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
riskBuilder.publishKey("myPublishKey");
riskBuilder.setFilterExpression("data.position[\"size\"] <= meta.limits[\"maxPosition\"] && !(meta.restrictions CONTAINS \"dayTrading\")");
PubNub riskPubNub = PubNub.create(riskBuilder.build());
show all 23 lines// Trading signal filtering
// This filter delivers cryptocurrency price alerts only when prices exceed user-defined thresholds,
// enabling personalized trading notifications while filtering out irrelevant market movements.
PNConfiguration tradingConfig = new PNConfiguration(new UserId("myUserId"));
tradingConfig.SubscribeKey = "mySubscribeKey";
tradingConfig.PublishKey = "myPublishKey";
tradingConfig.FilterExpression = "data.symbol LIKE \"CRYPTO*\" && data.price > meta.user[\"minPrice\"]";
Pubnub tradingPubNub = new Pubnub(tradingConfig);
// Risk management
// This filter enforces trading limits and compliance rules by monitoring position sizes and account restrictions,
// providing automated risk controls to prevent unauthorized or excessive trading activity.
PNConfiguration riskConfig = new PNConfiguration(new UserId("myUserId"));
riskConfig.SubscribeKey = "mySubscribeKey";
riskConfig.PublishKey = "myPublishKey";
show all 26 lines# Trading signal filtering
# This filter delivers cryptocurrency price alerts only when prices exceed user-defined thresholds,
# enabling personalized trading notifications while filtering out irrelevant market movements.
trading_config = PNConfiguration()
trading_config.publish_key = "myPublishKey"
trading_config.subscribe_key = "mySubscribeKey"
trading_config.user_id = "myUserId"
trading_config.filter_expression = 'data.symbol LIKE "CRYPTO*" && data.price > meta.user["minPrice"]'
trading_pubnub = PubNub(trading_config)
# Risk management
# This filter enforces trading limits and compliance rules by monitoring position sizes and account restrictions,
# providing automated risk controls to prevent unauthorized or excessive trading activity.
risk_config = PNConfiguration()
risk_config.publish_key = "myPublishKey"
show all 29 linesLimitations and workarounds
Use these workarounds when a field isn’t directly filterable. Add the value to metadata or the payload and filter on it.
Publisher filtering workaround
Since you cannot directly filter on publisher UUID, include publisher information in metadata:
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Publishing with publisher info in metadata
await pubnub.publish({
channel: 'updates',
message: { text: 'Hello World' },
meta: {
publisher: pubnub.getUserId(), // Include publisher in metadata
region: 'San Francisco'
}
});
// Filter based on publisher metadata
pubnub.setFilterExpression('meta.publisher != "' + pubnub.getUserId() + '"'); // Filter out own messages
// Publishing with publisher info
pubnub.publish(
channel: "updates",
message: ["text": "Hello World"],
meta: [
"publisher": pubnub.configuration.userId,
"region": "San Francisco"
]
)
// Filter based on publisher metadata
let filterConfig = PubNubConfiguration(
publishKey: "myPublishKey",
subscribeKey: "mySubscribeKey",
userId: "myUserId",
show all 18 lines// Publishing with publisher info
[self.pubnub publish:@{@"text": @"Hello World"}
toChannel:@"updates"
withMetadata:@{@"publisher": self.pubnub.currentConfiguration.uuid,
@"region": @"San Francisco"}
completion:nil];
// Filter based on publisher metadata
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
NSString *filter = [NSString stringWithFormat:@"meta.publisher != \"%@\"", config.uuid];
config.filterExpression = filter;
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Publishing with publisher info
Map<String, Object> metadata = new HashMap<>();
metadata.put("publisher", pubNub.getConfiguration().getUserId().getValue());
metadata.put("region", "San Francisco");
pubNub.publish()
.channel("updates")
.message(Collections.singletonMap("text", "Hello World"))
.meta(metadata)
.sync();
// Filter based on publisher metadata
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("meta.publisher != \"" + "myUserId" + "\"");
show all 16 lines// Publishing with publisher info
var metadata = new Dictionary<string, object> {
{"publisher", pubnub.PNConfig.UserId},
{"region", "San Francisco"}
};
pubnub.Publish()
.Channel("updates")
.Message(new { text = "Hello World" })
.Meta(metadata)
.Execute();
// Filter based on publisher metadata
pnconfig.FilterExpression = $"meta.publisher != \"{pubnub.PNConfig.UserId}\"";
# Publishing with publisher info
pubnub.publish(
channel="updates",
message={"text": "Hello World"},
meta={
"publisher": pubnub.config.user_id,
"region": "San Francisco"
}
).sync()
# Filter based on publisher metadata
pnconfig.filter_expression = f'meta.publisher != "{pubnub.config.user_id}"'
Message type filtering workaround
- JavaScript
- Swift
- Objective-C
- Java
- C#
- Python
// Include message type in payload or metadata
await pubnub.publish({
channel: 'alerts',
message: {
text: 'System Alert',
type: 'alert' // Include type in payload for filtering
},
meta: {
msgType: 'alert', // Alternative: include in metadata
priority: 'high'
}
});
// Filter by message type
pubnub.setFilterExpression('data.type == "alert"'); // Via payload
show all 16 lines// Publishing with type information
pubnub.publish(
channel: "alerts",
message: [
"text": "System Alert",
"type": "alert"
],
meta: [
"msgType": "alert",
"priority": "high"
]
)
// Filter by type via configuration
let typeConfig = PubNubConfiguration(
show all 21 lines// Publishing with type information
[self.pubnub publish:@{@"text": @"System Alert", @"type": @"alert"}
toChannel:@"alerts"
withMetadata:@{@"msgType": @"alert", @"priority": @"high"}
completion:nil];
// Filter by type via configuration
PNConfiguration *config = [PNConfiguration configurationWithPublishKey:@"myPublishKey"
subscribeKey:@"mySubscribeKey"];
config.uuid = @"myUserId";
config.filterExpression = @"data.type == \"alert\"";
PubNub *pubnub = [PubNub clientWithConfiguration:config];
// Publishing with type information
Map<String, Object> message = new HashMap<>();
message.put("text", "System Alert");
message.put("type", "alert");
Map<String, Object> metadata = new HashMap<>();
metadata.put("msgType", "alert");
metadata.put("priority", "high");
pubNub.publish().channel("alerts").message(message).meta(metadata).sync();
// Filter by type via configuration
PNConfiguration.Builder configBuilder = PNConfiguration.builder(new UserId("myUserId"), "mySubscribeKey");
configBuilder.publishKey("myPublishKey");
configBuilder.setFilterExpression("data.type == \"alert\"");
show all 16 lines// Publishing with type information
var message = new { text = "System Alert", type = "alert" };
var metadata = new { msgType = "alert", priority = "high" };
pubnub.Publish().Channel("alerts").Message(message).Meta(metadata).Execute();
// Filter by type
pnconfig.FilterExpression = "data.type == \"alert\"";
# Publishing with type information
pubnub.publish(
channel="alerts",
message={
"text": "System Alert",
"type": "alert"
},
meta={
"msgType": "alert",
"priority": "high"
}
).sync()
# Filter by type
pnconfig.filter_expression = 'data.type == "alert"'
Performance optimization
Use these guidelines to keep filter evaluation fast and resource‑efficient at scale.
Filter efficiency guidelines
Efficiency | Technique | Example |
---|---|---|
Most efficient | Direct field comparisons | meta.priority == "high" |
Most efficient | Numeric operations | data.score > 100 |
Most efficient | Simple AND conditions | field1 == "value" && field2 > 5 |
Moderately efficient | Pattern matching | field LIKE "prefix*" |
Moderately efficient | Array/object access | meta.array[0] == "value" |
Moderately efficient | Arithmetic operations | meta.id % 10 == 0 |
Use sparingly | Complex arithmetic | (field1 + field2) * field3 > threshold |
Use sparingly | Long OR chains | Many || conditions |
Use sparingly | Nested patterns | Multiple LIKE/CONTAINS in one expression |
Metadata design for filtering
Structure your metadata to optimize filter performance:
// Efficient metadata structure
meta: {
priority: "high", // Direct string access
userTier: "premium", // Flattened user information
categoryFlags: "news,urgent", // Comma-separated for CONTAINS
computedScore: 85, // Pre-calculated values
permissions: { // Single-level nesting
read: "true",
write: "false"
}
}
// Less efficient structure
meta: {
user: {
show all 23 linesTroubleshooting
Use these checks to diagnose and fix filter expression problems.
Common filter expression errors
Start with these frequent mistakes.
Syntax issues
// INCORRECT: Boolean literal
meta.active == true
// CORRECT: String comparison
meta.active == "true"
// WRONG: Assignment operator
meta.priority = "high"
// CORRECT: Equality operator
meta.priority == "high"
Field access issues
// INCORRECT: Direct envelope field access
publisher == "alice"
uuid == "user123"
// CORRECT: Include in metadata
meta.publisher == "alice" // (must be included when publishing)
Object access issues
// INCORRECT: Multi-level chaining
meta.data["users"][0] == "alice"
// CORRECT: Single-level access
meta.users[0] == "alice"
Filter expression reference
This section lists supported operators and data types for subscribe filter expressions.
Complete operator support
Operator | Type | Description | Example |
---|---|---|---|
== | Comparison | Equality | meta.status == "active" |
!= | Comparison | Inequality | data.type != "debug" |
> | Comparison | Greater than | meta.level > 5 |
< | Comparison | Less than | data.score < 100 |
>= | Comparison | Greater or equal | meta.priority >= 3 |
<= | Comparison | Less or equal | data.size <= 1024 |
LIKE | Pattern | Wildcard matching | meta.title LIKE "news*" |
CONTAINS | Pattern | Substring search | data.tags CONTAINS "urgent" |
&& | Logical | AND | meta.active == "true" && data.score > 50 |
|| | Logical | OR | meta.priority == "high" || data.urgent == "true" |
! | Logical | NOT | !(data.type == "system") |
% | Arithmetic | Modulo | meta.userId % 10 == 0 |
+ | Arithmetic | Addition | meta.base + 5 > 20 |
- | Arithmetic | Subtraction | data.total - data.used < 10 |
* | Arithmetic | Multiplication | meta.rate * 100 > 50 |
/ | Arithmetic | Division | data.total / data.count > 5 |
[n] | Access | Array element | meta.tags[0] == "urgent" |
["key"] | Access | Object property | meta.user["role"] == "admin" |
Data type support
Data Type | Syntax | Example | Notes |
---|---|---|---|
String | "value" | meta.name == "Alice" | Always quote string values |
Number | 123 , 3.14 | data.score > 85 | No quotes for numeric values |
Boolean | "true" , "false" | meta.enabled == "true" | Use strings, not literals |
Array | [index] | meta.tags[0] | Zero-based indexing |
Object | ["key"] | meta.user["role"] | Use double quotes for keys |
Best practices
Use these guidelines to design, implement, and monitor efficient filters.
Filter design
- Design metadata with filtering in mind from the start
- Use specific field names rather than generic terms
- Include computed values to avoid complex arithmetic
- Flatten nested structures where possible for performance
- Keep data types consistent across similar fields
Expression construction
- Start simple; test equality before adding complexity
- Use parentheses to make operator precedence explicit
- Put selective conditions first in AND expressions
- Build complex filters incrementally
Performance monitoring
- Monitor filter impact on message throughput
- Prefer numeric comparisons over string operations when possible
- Cache filter expressions instead of rebuilding them
Subscribe filters provide a comprehensive solution for sophisticated real-time message routing, enabling fine-grained control over message delivery based on content, metadata, and complex business logic while maintaining optimal performance characteristics.