Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
The Azure Web PubSub filter
parameter defines inclusion or exclusion criteria for sending messages to connections. This parameter is used in the Send to all, Send to group, and Send to user operations.
This article provides the following resources:
- A description of the OData syntax of the
filter
parameter with examples. - A description of the complete Extended Backus-Naur Form (EBNF) grammar.
A filter in the OData language is a Boolean expression. It can be one of several expression types, as shown in the EBNF description.
You can use an interactive syntax diagram to explore the syntax grammar rules.
The Formal grammar section of this article provides the complete EBNF.
By using the filter syntax, you can control sending messages to connections that match the identifier criteria. Azure Web PubSub supports the following identifiers:
Identifier | Description | Note | Example |
---|---|---|---|
userId |
The user ID of the connection | Case insensitive. It can be used in string operations. | userId eq 'user1' |
connectionId |
The connection ID of the connection | Case insensitive. It can be used in string operations. | connectionId ne '123' |
groups |
The collection of groups that the connection is currently in | Case insensitive. It can be used in collection operations. | 'group1' in groups |
Identifiers refer to the property value of a connection. Azure Web PubSub supports three identifiers that match the property name of the connection model. The service supports the userId
and connectionId
identifiers in string operations, and it supports the groups
identifier in collection operations.
For example, to filter out connections with a user ID of user1
, you specify the filter as userId eq 'user1'
. Read through the following sections for more examples of using the filter.
The expression for a filter is a Boolean expression. Azure Web PubSub sends messages to connections with filter expressions evaluated to true
.
The types of Boolean expressions include:
- Logical expressions that combine other Boolean expressions by using the operators
and
,or
, andnot
. - Comparison expressions, which compare fields or range variables to constant values by using the operators
eq
,ne
,gt
,lt
,ge
, andle
. - The Boolean literals
true
andfalse
. These constants can be useful sometimes when you're programmatically generating filters. Otherwise, they don't tend to be used in practice. - Boolean expressions in parentheses. Using parentheses helps to explicitly determine the order of operations in a filter. The Operator precedence section of this article describes the default precedence of the OData operators.
The filter syntax supports the following operations:
Operator | Description | Example |
---|---|---|
Logical operators | ||
and |
Logical and | length(userId) le 10 and length(userId) gt 3 |
or |
Logical or | length(userId) gt 10 or length(userId) le 3 |
not |
Logical negation | not endswith(userId, 'milk') |
Comparison operators | ||
eq |
Equal | userId eq 'user1' , userId eq null |
ne |
Not equal | userId ne 'user1' , userId ne null |
gt |
Greater than | length(userId) gt 10 |
ge |
Greater than or equal | length(userId) ge 10 |
lt |
Less than | length(userId) lt 3 |
le |
Less than or equal | 'group1' in groups , user in ('user1','user2') |
In operator | ||
in |
Right operand must be either a comma-separated list of primitive values, enclosed in parentheses, or a single expression that resolves to a collection | userId ne 'user1' |
Grouping operator | ||
() |
Controls the evaluation order of an expression | userId eq 'user1' or (not (startswith(userId,'user2')) |
String functions | ||
string tolower(string p) |
Gets the lower case for the string value | tolower(userId) eq 'user1' can match connections for user USER1 |
string toupper(string p) |
Gets the upper case for the string value | toupper(userId) eq 'USER1' can match connections for user user1 |
string trim(string p) |
Trims the string value | trim(userId) eq 'user1' can match connections for user user1 |
string substring(string p, int startIndex) ,string substring(string p, int startIndex, int length) |
Substring of the string | substring(userId,5,2) eq 'ab' can match connections for user user-ab-de |
bool endswith(string p0, string p1) |
Checks if p0 ends with p1 |
endswith(userId,'de') can match connections for user user-ab-de |
bool startswith(string p0, string p1) |
Checks if p0 starts with p1 |
startswith(userId,'user') can match connections for user user-ab-de |
int indexof(string p0, string p1) |
Gets the index of p1 in p0 , or returns -1 if p0 doesn't contain p1 |
indexof(userId,'-ab-') ge 0 can match connections for user user-ab-de |
int length(string p) |
Gets the length of the input string | length(userId) gt 1 can match connections for user user-ab-de |
Collection function | ||
int length(collection p) |
Gets the length of the collection | length(groups) gt 1 can match connections in two groups |
If you write a filter expression with no parentheses around its subexpressions, the Azure Web PubSub service will evaluate it according to a set of operator precedence rules. These rules are based on which operators are used to combine subexpressions. The following table lists groups of operators in order from highest to lowest precedence:
Group | Operators |
---|---|
Logical operators | not |
Comparison operators | eq , ne , gt , lt , ge , le |
Logical operators | and |
Logical operators | or |
An operator that's higher in the preceding table will "bind more tightly" to its operands than other operators do. For example, and
has higher precedence than or
, and comparison operators have higher precedence than either of them. So, the following two expressions are equivalent:
length(userId) gt 0 and length(userId) lt 3 or length(userId) gt 7 and length(userId) lt 10
((length(userId) gt 0) and (length(userId) lt 3)) or ((length(userId) gt 7) and (length(userId) lt 10))
The not
operator has the highest precedence of all. It's even higher than the comparison operators. If you write a filter like this:
not length(userId) gt 5
You'll get this error message:
Invalid syntax for 'not length(userId)': Type 'null', expect 'bool'. (Parameter 'filter')
This error happens because the operator is associated with just the length(userId)
expression, and not with the entire comparison expression. The length(userId)
expression is of type null
when userId
is null
. The fix is to put the operand of not
in parentheses:
not (length(userId) gt 5)
There are limits to the size and complexity of filter expressions that you can send to the Azure Web PubSub service. The limits are based roughly on the number of clauses in your filter expression. A good guideline is that if you have more than 100 clauses, you're at risk of exceeding the limit. To avoid exceeding the limit, design your application so that it doesn't generate filters of unbounded size.
Send to multiple groups:
filter='group1' in groups or 'group2' in groups or 'group3' in groups
Send to multiple users in a specific group:
filter=userId in ('user1', 'user2', 'user3') and 'group1' in groups
Send to a user but not a specific connection ID:
filter=userId eq 'user1' and connectionId ne '123'
Send to a user who's not in a specific group:
filter=userId eq 'user1' and (not ('group1' in groups))
Escape '
when the user ID contains '
:
filter=userId eq 'user''1'
The following Extended Backus-Naur Form grammar can describe the subset of the OData language that the Azure Web PubSub service supports. This grammar lists rules "top down," by starting with the most complex expressions and then breaking them down into more primitive expressions. The top is the grammar rule for $filter
that corresponds to the specific filter
parameter of the Azure Web PubSub service's Send*
REST APIs.
/* Top-level rule */
filter_expression ::= boolean_expression
/* Identifiers */
string_identifier ::= 'connectionId' | 'userId'
collection_identifier ::= 'groups'
/* Rules for $filter */
boolean_expression ::= logical_expression
| comparison_expression
| in_expression
| boolean_literal
| boolean_function_call
| '(' boolean_expression ')'
logical_expression ::= boolean_expression ('and' | 'or') boolean_expression
| 'not' boolean_expression
comparison_expression ::= primary_expression comparison_operator primary_expression
in_expression ::= primary_expression 'in' ( '(' primary_expression (',' primary_expression)* ')' ) | collection_expression
collection_expression ::= collection_variable
| '(' collection_expression ')'
primary_expression ::= primary_variable
| function_call
| constant
| '(' primary_expression ')'
string_expression ::= string_literal
| 'null'
| string_identifier
| string_function_call
| '(' string_expression ')'
primary_variable ::= string_identifier
collection_variable ::= collection_identifier
comparison_operator ::= 'gt' | 'lt' | 'ge' | 'le' | 'eq' | 'ne'
/* Rules for constants and literals */
constant ::= string_literal
| integer_literal
| boolean_literal
| 'null'
boolean_literal ::= 'true' | 'false'
string_literal ::= "'"([^'] | "''")*"'"
digit ::= [0-9]
sign ::= '+' | '-'
integer_literal ::= sign? digit+
boolean_literal ::= 'true' | 'false'
/* Rules for functions */
function_call ::= indexof_function_call
| length_function_call
| string_function_call
| boolean_function_call
boolean_function_call ::= endsWith_function_call
| startsWith_function_call
| contains_function_call
string_function_call ::= tolower_function_call
| toupper_function_call
| trim_function_call
| substring_function_call
| concat_function_call
/* Rules for string functions */
indexof_function_call ::= "indexof" '(' string_expression ',' string_expression ')'
concat_function_call ::= "concat" '(' string_expression ',' string_expression ')'
contains_function_call ::= "contains" '(' string_expression ',' string_expression ')'
endsWith_function_call ::= "endswith" '(' string_expression ',' string_expression ')'
startsWith_function_call ::= "startswith" '(' string_expression ',' string_expression ')'
substring_function_call ::= "substring" '(' string_expression ',' integer_literal (',' integer_literal)? ')'
tolower_function_call ::= "tolower" '(' string_expression ')'
toupper_function_call ::= "toupper" '(' string_expression ')'
trim_function_call ::= "trim" '(' string_expression ')'
/* Rules for string and collection functions */
length_function_call ::= "length" '(' string_expression | collection_expression ')'
Use these resources to start building your own application: