Purpose
A filter expression is a string that conforms to the Open Data Model filter grammar and that is applied to the properties of a node or a relation to reduce/filter out some instances.
Grammar
Any property name involved in a filter expression must exist on the object (node or relation) it applies to. The values used in comparison expressions must be specified according to the property type they refer to.
PropertyType | Value expression |
---|---|
String | a string surrounded by single quotes |
Int | any integer value, prefixed by '+' or '-' if needed |
Float | any float value, prefixed by '+' or '-' if needed |
ID | any integer value, prefixed by '+' or '-' if needed if the underlying type is expected to be Int or a string surrounded by single quotes if the underlying type is expected to be String |
Boolean | 0 or 1 |
DateTime | 'yyyy-MM-dd hh:mm:ss' |
A comparison value may also represent an array. In such cas, comma-separated values must be enclosed by '[' ']'
Tip
Although the grammar is case-insensitive, writing grammar terms in upper case increases the readability of the expressions.
Caution
Data Hub entities (DataHubSite, DataHubSource or DataHubVariable) support filtering on 2 properties only, Id or Name.
Syntax
Comparison with scalar value
Syntax:
property_name operator value
Operator | Applies to type | Evaluation result |
---|---|---|
= | any | true if property_name value is equal to the value. String comparison is case-sensitive |
<> | any | true if property_name value is not equal to the value. String comparison is case-sensitive |
> | any | true if property_name value is greater than the value. String comparison is case-sensitive |
>= | any | true if property_name value is greater than or equal to the value. String comparison is case-sensitive |
< | any | true if property_name value is lower than the value. String comparison is case-sensitive |
<= | any | true if property_name value is greater than or equal to the value. String comparison is case-sensitive |
STARTS WITH | String | true if property_name value starts with the string value. String comparison is case-sensitive |
ENDS WITH | String | true if property_name value ends with the string value. String comparison is case-sensitive |
CONTAINS | String | true if property_name value contains the string value. String comparison is case-sensitive |
LIKE | String | true if property_name value contains the string value. String comparison is case-sensitive |
IN | any | true if property_name value is part of the list of values |
Comparison with scalar value of an optional property
Syntax:
OPTIONAL(property_name) operator value
Without the OPTIONAL, if property_name does not exist, the evaluation result will always be false, regardless of the operator. Using OPTIONAL(property_name) instructs the Open Data Model engine to apply the comparison if and only if the property does exist.
This is usefull e.g when a relation property is not set in most of the cases but set on sepecific conditions. Let's imagine a relation property named IsBlocked that is set only upon rare situation. The expression OPTIONAL(IsBlocked) = 0 will evaluate to true if the IsBlocked property does not exist or is equal to 0 but will evaluate to false if the IsBlocked property equals to 1.
Comparison with NULL
Syntax:
property_name IS NULL
The evaluation result is true if property_name value is null or does not exist
Tip
Providing that all targeted entities have a property named "XYZ", the filter NOT XYZ IS NULL behaves like a wildcard filter, evaluating to true for all entities having this property.
Negate comparison
Syntax:
NOT property_name operator value
Using NOT inverts the comparison result. Although this operator applies to any comparison, it is escpecially useful for operators that do not have their conterpart, such as CONTAINS, STARTS WITH, ENDS WITH, IN.
The typical use of this operator is 'NOT property_name IN [1,2]'
Combine expressions
Binary combination operators allow to combine multiple expressions.
Binary operator | Evaluation result |
---|---|
AND | true if left and right expressions are true |
OR | true if left or right expressions is true |
XOR | true if only left expression or only right expressions is true |
Controlling operator precedence
By default, AND has higher precedence than OR and XOR. Parentheses allow to force precedence.
comp1 AND comp2 OR comp3 defaults to (comp1 AND comp2) OR comp3
comp1 AND (comp2 OR comp3) first evaluates the OR operator then the AND one.
Lexer
STRING
: '"' (~('"' | '\\' | '\r' | '\n') | '_' | '-' |'\\' ('"' | '\\'))* '"'
| '\'' (~('\'' | '\\' | '\r' | '\n') | '_' | '-' |'\\' ('\'' | '\\'))* '\''
;
COMMA: ',';
SIGN: ('+' | '-');
LETTER : [a-zA-Z_] ;
DIGIT : [0-9] ;
LEFTPARENTHESIS: '(';
RIGHTPARENTHESIS: ')';
LEFTSQUAREBRACKET: '[';
RIGHTSQUAREBRACKET: ']';
NOT: 'NOT';
OR: 'OR';
AND: 'AND';
XOR: 'XOR';
STARTS : 'STARTS';
ENDS : 'ENDS';
WITH: 'WITH';
IS: 'IS';
NULL: 'NULL';
IN : 'IN';
LIKE : 'LIKE';
CONTAINS : 'CONTAINS';
PARENT : 'PARENT';
OPTIONAL : 'OPTIONAL';
IDENTIFIER: (LETTER + (LETTER | DIGIT)*);
STARTSWITH : STARTS WS+ WITH;
ENDSWITH : ENDS WS+ WITH;
ISNULL : IS WS+ NULL;
EQ : '=' ;
NEQ: '<>';
GT: '>';
GTE: '>=';
LT: '<';
LTE: '<=';
WS: [ \t\r\n] -> skip;
Parser
grammar
: binaryExpression | compareExpression;
binaryExpression
: binaryExpression AND binaryExpression
| binaryExpression OR binaryExpression
| binaryExpression XOR binaryExpression
| compareExpression
| NOT? compareExpression
| LEFTPARENTHESIS binaryExpression RIGHTPARENTHESIS
;
compareExpression
: propertyExpression operatorExpression valueExpression
| parentExpression operatorExpression valueExpression
| propertyExpression ISNULL
;
propertyExpression
: optionalExpression
| propertyIdentifierExpression
;
propertyIdentifierExpression
: LETTER | IDENTIFIER
;
operatorExpression
: EQ | NEQ | GT | GTE | LT | LTE | LIKE | CONTAINS | STARTSWITH | ENDSWITH
;
parentExpression
: PARENT LEFTPARENTHESIS nodeTypeExpression COMMA propertyIdentifierExpression RIGHTPARENTHESIS
;
optionalExpression
: OPTIONAL LEFTPARENTHESIS propertyIdentifierExpression RIGHTPARENTHESIS
;
nodeTypeExpression
: propertyIdentifierExpression
;
listExpression
: LEFTSQUAREBRACKET valueExpression (COMMA valueExpression)* RIGHTSQUAREBRACKET
;
valueExpression
: STRING
| numberExpression
;
numberExpression
: SIGN? ( DIGIT* '.' )? DIGIT+
;