Eloqua expression language
The Eloqua expression language (EEL) support for incorporating logic into decision making
and filtering within Eloqua replaces the ExportFilter
data transfer
object that was present in Bulk 1.0. EEL simplifies and formalizes the
syntax, providing a consistent way to interact with your data.
Operators
Comparison Operators
- >
- >=
- <
- <=
- !=
- =
- ~ (This is the SQL Server LIKE operator. see: Like (Transact-SQL) on the Microsoft Developer Network documentation for appropriate syntax.)
Logical operators
Existence operators
EEL includes the EXISTS
and STATUS
operators as ways to filter
based on a contacts’ presence or absence in a container, or on the status
of associated containers. Unlike the comparison and logical operators,
EXISTS
and STATUS
can only act on certain entities.
Note: You can only use one EXISTS and STATUS operator in a filter.
EXISTS
EXISTS
is analogous to an IN
operator. It determines if the object or
entity exists within a container. The valid entities are: contact filters,
contact segments, contact lists, and account Lists, as in the following examples:
EXISTS('{{ContactFilter[<id>]}}')
EXISTS('{{ContactSegment[<id>]}}')
EXISTS('{{ContactList[<id>]}}')
EXISTS('{{AccountList[<id>]}}')
The <id>
being the entity's id
(e.g. 12).
EXISTS
operators can only be used on exports of the same entity:
- The ContactList, ContactFilter, or ContactSegment
EXISTS
operators can only be used in filters for contact exports. - The AccountList
EXISTS
operator can only be used in filters for account exports.
STATUS
STATUS
describes the current status of a cloud connector, or AppCloud action,
content, or decision service. STATUS
does not currently support accessing
email groups, campaigns, and so on.
For cloud connectors, use the following format:
STATUS('CloudConnectorStatus(<instanceid>)') = '<status>'
Where the <instanceid>
is the instance’s ID, and <status>
is
either active or pending.
For AppCloud actions and decisions, the following format is correct:
STATUS('{{DecisionInstance(<instanceId>).Execution[<executionId>]}}') = '<status>'
STATUS('{{ActionInstance(<instanceId>).Execution[<executionId>]}}') = '<status>'
For AppCloud feeders the following format is correct:
STATUS('{{FeederInstance(<instanceId>)}}') = '<status>'
The <instanceId>
being the GUID for the specific instance of the AppCloud service being used, and the <executionId>
being the integer identifying a unique AppCloud service instance's execution. The <status>
can be active, pending, complete, or errored.
The STATUS
can also be invalid
for AppCloud actions and decisions.
Examples
Comparison
Select contacts whose CreatedAt
field is greater that 2018-12-31:
"filter" : "'{{Contact.CreatedAt}}' > '2018-12-31'"
Select contacts whose Account’s Company Name is not Eloqua:
"filter" : "'{{Contact.Account.Field(M_CompanyName)}}' != 'Eloqua'"
Select contact with email address "test.a'pie@test.test":
"filter": "'{{Contact.Field(C_EmailAddress)}}'='test.a\\'pie@test.test'"
Logical
Supported filter formats with logical operators:
- (A OR B) AND (C OR D)
- A AND NOT B AND (C OR D)
- A AND B AND (C OR D)
- A AND (B OR C)
Note: Activity exports only support the A AND B AND C filter format.
Select contacts whose CreatedAt
field is greater that 2018-12-31 and
whose account's company name is not Eloqua:
"filter" : "'{{Contact.CreatedAt}}' > '2018-12-31' AND '{{Contact.Account.Field(M_CompanyName)}}' != 'Eloqua'"
Select contacts whose CreatedAt
field is greater than 2018-12-31 and
whose account's company name is not Eloqua and whose C_Country
field is
Canada or United States:
"filter": "'{{Contact.CreatedAt}}' > '2018-12-31' AND '{{Contact.Account.Field(M_CompanyName)}}' != 'Eloqua' AND ('{{Contact.Field(C_Country)}}' = 'CA' OR '{{Contact.Field(C_Country)}}' = 'US')"
Existence
EXISTS
refers specifically to a container. The following filters
contacts based on their presence in the ContactList with id
123:
"filter" : "EXISTS('{{ContactList[123]}}')"
STATUS
. The following filter selects records for which the AppCloud action service instance ID is f82d50cd86a94fcab37e4ec9a98b0339, with an execution ID of 12345 and a status is pending:
"filter" : "STATUS('{{ActionInstance(f82d50cd86a94fcab37e4ec9a98b0339).Execution[12345]}}') = 'pending'"
Note: Filters have a 1000 character limit. Contact fields cannot be used in the filter for activity exports.
Grammar
grammar Ebl;
options {
language = CSharp3;
output = AST;
backtrack = true;
}
@modifier{public}
@parser::namespace { Eloqua.Expression.Version1.Grammar }
@lexer::namespace { Eloqua.Expression.Version1.Grammar }
public expression
: WS!? orExpression WS!? EOF
;
orExpression
: andExpression (WS!? OR^ WS!? andExpression)*
;
andExpression
: notExpression (WS!? AND^ WS!? notExpression)*
;
notExpression
: (NOT WS!?)? atom
;
subExpression
: OPENPAREN! orExpression WS!? CLOSEPAREN!
;
atom
: comparison
| subExpression
;
comparison
: STRING WS!? GREATERTHAN WS!? STRING
| STRING WS!? GREATERTHANOREQUAL WS!? STRING
| STRING WS!? LESSTHAN WS!? STRING
| STRING WS!? LESSTHANOREQUAL WS!? STRING
| STRING WS!? NOTEQUAL WS!? STRING
| STRING WS!? EQUAL WS!? STRING
| STRING WS!? LIKE WS!? STRING
| EXISTS WS!? OPENPAREN! WS!? STRING WS!? CLOSEPAREN!
| STATUS WS!? OPENPAREN! WS!? STRING WS!? CLOSEPAREN! WS!? EQUAL! WS!? STRING
;
// Lexer tokens
// Comparison Operators
GREATERTHAN : '>' ;
GREATERTHANOREQUAL : '>=' ;
LESSTHAN : '<' ;
LESSTHANOREQUAL : '<=' ;
NOTEQUAL : '!=' ;
EQUAL : '=' ;
LIKE : '~' ;
// Existence Operators
EXISTS : E X I S T S ;
STATUS : S T A T U S ;
// Binary
AND : A N D;
OR : O R;
// Unary
NOT : N O T;
// Grouping
OPENPAREN : '(' ;
CLOSEPAREN : ')' ;
// Lexer rules
STRING : QUOTE ( ESC_SEQ | ~('\\'|'\'') )* QUOTE;
WS : (' '|'\t'|'\n'|'\r')+ ;
fragment
ESC_SEQ
: '\\' ('b'|'t'|'n'|'f'|'r'|'\"'|'\''|'\\')
| '\\' 'u' HEX_DIGIT HEX_DIGIT HEX_DIGIT HEX_DIGIT
;
fragment QUOTE : '\'' ;
fragment HEX_DIGIT : ('0'..'9'|'a'..'f'|'A'..'F') ;
fragment A:('a'|'A');
fragment B:('b'|'B');
fragment C:('c'|'C');
fragment D:('d'|'D');
fragment E:('e'|'E');
fragment F:('f'|'F');
fragment G:('g'|'G');
fragment H:('h'|'H');
fragment I:('i'|'I');
fragment J:('j'|'J');
fragment K:('k'|'K');
fragment L:('l'|'L');
fragment M:('m'|'M');
fragment N:('n'|'N');
fragment O:('o'|'O');
fragment P:('p'|'P');
fragment Q:('q'|'Q');
fragment R:('r'|'R');
fragment S:('s'|'S');
fragment T:('t'|'T');
fragment U:('u'|'U');
fragment V:('v'|'V');
fragment W:('w'|'W');
fragment X:('x'|'X');
fragment Y:('y'|'Y');
fragment Z:('z'|'Z');