How to use Message Selectors to filter messages
Message Selectors allow you to filter the messages that a MessageConsumer will receive. The filter is a relatively complex language that mimics the syntax of an SQL WHERE clause. The selector can use all message headers and properties for filtering, but can not use the message content.
Selectors are mostly useful for Topics that broadcast a very large number of messages to its subscribers.
They way selectors work depends on the destination type:
- On Queues, only messages that match the selector will be returned. Others stay in the queue (and thus can be read by a MessageConsumer with different selector).
- On Topics, messages that do not match the selector will be ignored as if they have not been published.
In order to create a selection, you need to pass it to the createConsumer or createDurableSubscriber invocation:
Session session = ...
MessageConsumer consumer = session.createConsumer(queue, "releaseYear < 1980");
The following SQL elements are allowed in the filter:
Element | Description | Example Selector |
---|---|---|
Header Fields | Any headers except JMSDestination, JMSExpiration and JMSReplyTo | JMSPriority = 9 |
Properties | Message properties that follow Java identifier naming | releaseYear = 1982 |
String Literals | String literals in single quotes, duplicate to escape | title = 'Sam''s' |
Number Literals | Numbers in Java syntax (int and double) | releaseYear = 1982 |
Boolean Literals | TRUE and FALSE | isAvailable = TRUE |
( ) | Brackets | (releaseYear < 1980) OR (releaseYear > 1989) |
AND, OR, NOT | Logical operators | (releaseYear < 1980) AND NOT (title = 'Thriller') |
=, <>, <, <=, >, >= | Comparison operators | (releaseYear < 1980) AND (title <> 'Thriller') |
LIKE | String comparison with wildcards '_' and '%' (more) | title LIKE 'Thrill%' |
IN | Find value in set of strings (more) | title IN ('Off the wall', 'Thriller', 'Bad') |
BETWEEN | Check whether number is in range (both numbers inclusive) (more) | releaseYear BETWEEN 1980 AND 1989 |
IS NULL, IS NOT NULL | Check whether value is null or not null. | releaseYear IS NOT NULL |
*, +, -, / | Arithmetic operators | releaseYear * 2 > 2000 - 20 |
Some more examples of message consumers with selectors:
Session session = ...
MessageConsumer consumer1 = session.createConsumer(queue,
"(releaseYear < 1980) OR (releaseYear > 1989)");
MessageConsumer consumer2 = session.createConsumer(queue,
"(releaseYear BETWEEN 1980 AND 1989) AND title LIKE 'Michael%'");
MessageConsumer consumer3 = session.createConsumer(queue,
"(releaseYear = 1982) OR (title = 'Thriller')");
MessageConsumer consumer4 = session.createDurableConsumer(queue,
"title IN ('Off the wall', 'Thriller', 'Bad')");