The Ad Forecaster accepts arbitrary boolean expressions as targeting and filtering rules.
Such boolean expressions can be comparisons (with the format key <operator>
value
), geo-targeting operations or a combination of expressions using boolean
operators (AND, OR and NOT).
For example, to target Firefox users near San Francisco, one could use the
following targeting rule: user-agent contains "Firefox" and userCoordinates
near (37.757815, -122.5076401) by 10 km
.
Supported Operators
Boolean operators
Operator | Meaning | Example |
---|---|---|
!, not | boolean “not” | !(country = "US") |
|, ||, or | boolean “or” | country = "US" | age < 50 |
&, &&, and | boolean “and” | age > 20 & age < 50 |
Comparison operators
Operator | Meaning | Example |
---|---|---|
=, ==, is | equal to | country = "US" |
<, lt | less than | age < 50 |
>, gt | greater than | age > 20 |
<= | less than or equal | age <= 50 |
>= | greater than or equal | age >= 20 |
in | present in list of items | country in ("US", "FR") |
contains | string contains | user-agent contains "Chrome" |
startsWith | string starts with | user-agent startsWith "Mozilla" |
endsWith | string ends with | user-agent endsWith "43.0" |
arrayContainsAny | array contains any | keywords arrayContainsAny ("blog", "article") |
arrayContainsAll | array contains all | keywords arrayContainsAll ("blog", "article") |
Geo targeting operators
Operator | Meaning | Example |
---|---|---|
near by | value near coordinate | userCoordinates near (41.176296, -8.596050) by 30 km |
Latitude and longitude coordinates should be defined in decimal degrees.
The supported units are km
for kilometers and mi
for miles.
Functions
Operator | Meaning | Example |
---|---|---|
isDefined | returns true if a variable is defined | isDefined(country) |
Undefined Variables
Sometimes a log row can have undefined variables (e.g. some users might not have a geo location).
When an undefined variable is used on a sub-expression, that sub-expression is evaluated to false
.
It is important to take this into account when negating sub-expressions. For example, if the variable age
is
undefined, age < 18
will evaluate to false
, but !(age >= 18)
will evaluate to true
.
This can be addressed by using the isDefined
function to check if a variable is defined
(e.g. isDefined(age) && age < 18
and isDefined(age) && !(age >= 18)
are the equivalent).
Accessing Indexed Variables
For keys that are described as being “indexable”
(FieldDescription), usually for container types
(array
and map
), it is possible to perform an indexing operation on the key in
order to access a specific element inside the container and create a rule.
For example, assuming a field dynamicTargeting
as an associative array from string to string
(map String -> String
), we are able to perform an indexing operation with the following
syntax dynamicTargeting["gender"]
. We can then create a valid rule like this:
dynamicTargeting["gender"] = "male"
.
For array
types, the index is the position of the element we’re trying to access (and the "
are not mandatory). E.g. arrayField[3] > 10
or arrayField["3"] > 10
.
Whenever an indexing operation fails (i.e. the specified key that’s being accessed doesn’t exist), it is treated as an undefined variable.
Additional Fields
Depending on the context, some additional fields might be available (e.g. dayOfWeek
).
Please refer to the API documentation to see which additional fields are available.
Useful Tips
- Instead of using multiple equalities, use the
in
operation, for example:gender = "m" || gender = "f"
→gender in ("m", "f")
);!(device = "phone") && !(device = "tablet")
→!(device in ("phone", "tablet"))
);
- You can do most wildcard-style string matches by combining string operations, for example:
*.sapo.pt
→domain endsWith ".sapo.pt"
www.facebook.*
→domain startsWith "www.facebook."
forecaster.*.adforecaster.com
→domain startsWith "forecaster." AND domain endsWith ".adforecaster.com"
*.twitter.*
→domain contains ".twitter."
- Use your domain knowledge to avoid tautological rules, for example:
dayOfWeek in (1,2,3,4,5,6,7)
→true
browser = "Edge" && operativeSystem in ("Windows", "Linux")
→browser = "Edge"
- Extract common expressions so that they are evaluated only once, for example:
(browser = "Edge" && gender = "f") || (browser = "Firefox" && gender = "f")
→gender = "f" && (browser in ("Edge", "Firefox"))