flowthings.io Filter Language


Filters can be used for explicit object matching, as well as members of Flow and Track objects, where they control the types of Drops that can enter a Track or Flow.

Filter Operators


Comparison TypeSyntax
Fixed Value ComparisonaMemberName (< or <= or == or > or >= or !=) aValue
Element Value ComparisonaMemberName (< or <= or == or > or >= or !=) bMemberName
ModuloaMemberName % X ( == or != ) Y
RegexaMemberName =~ aJavaRegex
INaMemberName IN ["value1", "value2", "value3"]
CONTAINSaMemberName CONTAINS ["value1", "value2", "value3"]
WITHINlocation WITHIN 5 MILES OF [40.703987, -73.986759]
EXISTSEXISTS aMemberName
HASHAS aDataType
AGEAGE (< or <= or == or > or >=) msSinceCreated or AGE ('fieldname') (< or <= or == or > or >=) msSinceCreated
MATCHESMATCHES /aJavaRegex/
NOTNOT aFilterRule

Fixed Value Comparison

Matches objects with member values that evaluate to true given the specified comparison to a fixed value:

Find all Drops in a given Flow where the element "aNumber" has a value less than or equal to 1:

HTTP 1.1 GET https://<base_url>/drop/<flowId>?filter=elems.aNumber<=1

Find all Drops in a given Flow where the element "shipped" is true:

HTTP 1.1 GET https://<base_url>/drop/<flowId>?filter=elems.shipped!=true

Find all Flows where the description is equal to "myFirstFlow":

HTTP 1.1 GET https://<base_url>/flow?filter=description=="myFirstFlow"

Find Tracks feeding a Flow whose path is /bob/:

HTTP 1.1 GET http://<base_url>/track?filter=destination=="/bob/"

Element Value Comparison

Matches objects with member values that evaluate to true given the specified comparison to the value of another member:

Find all Drops where the value of the element "length" equals the value of the element "width":

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.length<=elems.width

Find all Flows where the value of the description member equals the value of the path member:

HTTP 1.1 GET https://<base_url>/drop?filter=path==description

Modulo

Matches objects with member values that match the given modulo

Find all Drops where the counter is a multiple of 100:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.counter % 100 == 0

Regex

Matches objects with member values that evaluate to true when compared to the given regex.

Find all Drops in the given Flow where the value of the element "title" matches the regex /[cC]lojure/:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.title=~/[cC]lojure/

Find all Flows where the value of the path starts with /bob/:

HTTP 1.1 GET http://<base_url>/flow?filter=path=~/^\/bob\//

Find child Flows of the Flow whose path is /bob/:

HTTP 1.1 GET http://<base_url>/flow?filter=path=~/^\/bob\/[^\/]*$

Find all Tracks feeding Flows whose path starts with /bob/:

HTTP 1.1 GET http://<base_url>/flow?filter=destination=~/^\/bob\//

IN

Matches objects with member values that equal any item of the provided list.

Find all Drops where the value of the "status" element is either "shipped" or "delivered":

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.status IN ["shipped","delivered"]

Find all Tracks where the value of the "destination" element is either "/bob/myFirstFlow" or "/bob/mySecondFlow":

HTTP 1.1 GET http://<base_url>/track/<flowId>?filter=destination IN ["/bob/myFirstFlow","/bob/mySecondFlow"]

CONTAINS

Matches objects with a list member who's values contain all items of the provided list.

Find all Drops where the value of the "ingredients" element contains "vodka":

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.ingredients CONTAINS ["vodka"]

Find all Drops where the value of the "ingredients" element contains both "vodka" AND "gasoline":

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.ingredients CONTAINS ["vodka","gasoline"]

WITHIN

Matches objects with an element location that lies within the specified distance of the given location specifier.

Find all Drops with a location element that lies within 500 miles of 40.703987, -73.986759:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=location WITHIN 500 MILES OF [40.703987, -73.986759]

Find all Drops with a location element that lies within 20 kilometers of the specified zip code:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=location WITHIN 26.2 KILOMETERS OF [ZIP="11201"]

To learn more about the location data type, see Drop Data Types.

EXISTS

Matches objects with where the member or drop element exists and is not empty.

Find all Drops where the element "title" exists:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=EXISTS elems.title

Find all Flows where the member "filter" exists:

HTTP 1.1 GET http://<base_url>/flow?filter=EXISTS filter

HAS

Matches drop objects an element exists of the specified type.

Find all Drops where there is at least one element of the type "float":

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=HAS float

AGE

Matches objects with a date that evaluates to true when compared with the given specifiers. A "Duration" macro can be used to more easily specify longer durations, such as DAYS, HOURS, MINUTES, or SECONDS.

Find all Drops with a creation date in the last 3600000 miliseconds:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=AGE < 3600000

Find all Tracks which were created over a 2 months ago:

HTTP 1.1 GET http://<base_url>/track?filter=AGE < Duration(2,"MONTHS")

This can also be used to search in other date fields:

HTTP 1.1 GET http://<base_url>/track?filter=AGE("lastEditDate") < Duration(2,"MONTHS")

Or in drop element fields if the drops are storing dates:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=AGE("myDateField") < 3600000

MATCHES

Matches any object where members or drop elements which can reasonably be converted to a string. The MATCHES rule is intended for use when you may not know all of the member names needed for a query. If the member fields are known then one or more combined explicit Regex operators will always be more performant.

Find all Drops in the given flow where the value of any "stringable" field matches the regex /[cC]lojure/:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=MATCHES /[cC]lojure/

Find all Flows where the value of any "stringable" field matches the regex /[cC]lojure/:

HTTP 1.1 GET http://<base_url>/flow?filter=MATCHES /[cC]lojure/

NOTE: id fields will not be searched, instead use one or more combined regex filters.

NOT

Provides the inverse functionality of any filter rule.

Finds all Drops in the given Flow where the value of element "title" does not match [cC]lojure:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=NOT elems.title =~ /[cC]lojure/

Finds all Flows where the value of "description" member does not match [cC]lojure:

HTTP 1.1 GET http://<base_url>/flow?filter=NOT description =~ /[cC]lojure/

Combining Filters


Filters can be combined using logical &&, logical || and grouped.

Finds all Tracks to a Flow whose path is "/bob/destFlow" that contain a filter:

HTTP 1.1 GET http://<base_url>/track?filter=destination=="/bob/destFlow" && EXISTS filter

Finds all Drops in the given Flow with a "on-hand" element whose value is over 100 and "state" is not "cancelled":

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.on-hand>100 && NOT elems.state=="canceled"

Finds all Tracks to "/bob/sourceFlow" from Flows whose paths start with "/a" or end with "b"

HTTP 1.1 GET http://<base_url>/track?filter=source=="/bob/sourceFlow" && (destination=~/^\/a/ || to=~/b$/)

Filtering Complex Data Types


Some complex types also support a special syntax for addressing their names and values.

Date

Filter values for date types can be written...

As milliseconds since epoch, cast to a date type:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.theDate >= Date(1335412800000)

As integer milliseconds since epoch:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.theDate <= 1335412800000

Email

Filter values for email types can be written...

As a string, cast to an email type:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.theEmail == EMAIL("[email protected]")

As a string:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.theEmail == "[email protected]"

As a regex:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.theEmail =~ /abc.*/

Location

Filter values for location types can be written...

As a sub-element query:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=location.$zip == '11204'

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=location.$latitude > 40.123

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=location.$longitude > 80.111

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=location.$street == '155 Water Street'

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=location.$city == 'New York City'

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=location.$state == 'NY'

Media

Filter values for media types can be written...

As a sub-element query:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.theVideo.$url == 'http://www.example.com/puppyvskitten'

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.theVideo.$description != ''

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.theVideo.$title =~ /[Pp]uppies/

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.theVideo.$type == 'video'

Map

Filter values for map types can be written...

As a sub-element query, given a drop with element "a" a map whose values are { "b": 100, "c": Color(100,100,200) }:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.a.b == 100

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=elems.a.c.red == 100 && a.c.blue == 200

As a sub-element query, given a flow which receives drops from a track contains a transform function:

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=parent.$drop=='d0987654321012345BEEFDEAD'

HTTP 1.1 GET http://<base_url>/drop/<flowId>?filter=parent.$flow=='d0987654321012345BEEFDEAD'