Wiki

Clone wiki

neo4j-databridge / 6. Expression Language

6. Expression Language

Introduction

The Databridge Expression Language enables you to use condition expressions in order to evaluate whether a particular property, edge, node or label should be processed or not.

Condition expressions

Condition expressions are introduced using a condition attribute into individual graph element definitions in the schema mappings. Condition expressions are evaluated against the current row of data being processed, and return either true or false depending on whether the condition is met or not. If a condition expression returns false, the corresponding graph element is not processed for that row.

Grammar

All condition expressions are of the form "condition": "<bool-expr>", where bool-expr is defined according to the following grammar:

bool-expr     rel-expr {[OR, AND] rel-expr}
rel-expr      log-expr [GT, LT, GE, LE, EQ, NE, LIKE] log-expr
log-expr      term-expr {[LOGAND, LOGOR, LOGXOR] term-expr}
term-expr     factor-expr {[ADD, SUB] factor-expr}
factor-expr   unary-expr {[MUL, DIV, MOD] unary-expr}
unary-expr    NOT expr
              [INV, NEG] unary-expr
              primary-expr
primary-expr  LPAREN expr RPAREN
              [<constant>, <data-value>]



Notes: 

      { ... } means optionally followed by
      [ ... ] means select one of

Operators

The following is a comprehensive list of the operators you can use when creating expressions. Bear in mind that not all operators are valid for all data types (you can't add two Strings for example, or do a bitwise xor on floating-point values). If you try to use an operator in a context in which it is invalid, the importer will throw an exception, telling you what you did wrong.

Boolean conjunction, disjunction and negation

  • and conjunction
  • or disjunction
  • not negation

Arithmetic

binary

  • + addition
  • - subtraction
  • / division
  • * multiplication
  • % modulus

unary

  • - negation

Relational

  • == equal
  • != not equal
  • =~ matches regex
  • > greater than
  • < less than
  • >= greater than or equal
  • <= less then or equal

Logical (aka bitwise)

binary

  • & logical and
  • | logical or
  • ^ logical exclusive or

unary

  • ~ one's complement

Note: one omission from the bitwise operators currently are the shift operators. The following tokens are reserved for possible implementation at a future date.

  • lsl logical shift left
  • lsr logical shift right
  • asl arithmetic shift left
  • asr arithmetic shift right
  • ror rotate right
  • rol rotate left

Sub-expressions

  • (...) parentheses

Operator precedence rules

The evaluation order of operators should not yield any surprises. There are seven levels, with sub-expressions at the highest level and boolean conjunction and disjunction at the lowest. Operators within the same level are evaluated in the order in which they appear in the expression, i.e. from left to right.

Level Type Operators
1 sub-expressions (...)
2 unary not, -, ~
3 multiplicative *, /, %
4 additive +, -
5 bitwise &, |, ^
6 relational ==, !=, =~, >, >=, <, <=
7 boolean and, or

Example: conditional labels

In this example we add a SpaceStation label to any satellite that is Manned and whose Status is 1 (active)

#!java
"nodes": [
   {
     "type": "Satellite",
     "labels" [ 
         { "name": "SpaceStation", "condition": "Manned == 'Y' and Status == 1" }
         ... 
     ]
     ...
   }
]
...

Example: conditional properties

The following JSON snippet will create a historic property on each satellite node. If the satellite's name starts with 'Sputnik' then the value of the property will be "Y", otherwise the value will be "N".

#!java
"nodes": [
   {
     "type": "Satellite",
     "properties" [ 
         { "name": "historic", "value": "Y", "condition": "Object =~ 'Sputnik.*'", "default": "N" }
         ... 
     ]
     ...
   }
]
...

Example: conditional nodes

We can also exclude any satellite in a high-earth orbit (HEO) from the import.

#!java
"nodes": [
   {
     "type": "Satellite", 
     "condition": "Alt != 'HEO'"
     ...
   }
]
...

Example: conditional edges

We can create an edge called 'LIVE' between a satellite and the space program that launched it only if the satellite is still active (status = 1).

#!java

"edges" : [
    { "name": "LIVE", "source":"Satellite", "target":"SpaceProgram", "condition": "Status == 1" }
    ...
]
...

Hints and tips when using condition expressions

String, numeric and boolean constants are all permitted:

String Constants

String constants must be enclosed in single quotes. If the value itself contains a quote, as in "Bob's Motors", the internal quote should be escaped:

MOTCentre == 'Bob''s Motors'

Boolean constants

There are two boolean constants, true and false, with no variants in spelling or case:

Assigned == true

Matched == false

Note that String variables and constants are permissively evaluated for truthiness when appearing in equality expressions. Thus:

'True' == true is true and

'fAlSe' != true is also true, but

'true!' == true is false, or alternatively, not true

Numeric constants

Numeric constants can be integer or floating-point, e.g.

Count == 1

Limit < 3.25

Both integer and real-valued constants are represented internally as signed 64 bit values. The permissible bounds for an integer constant are:

−9,223,372,036,854,775,808 to +9,223,372,036,854,775,807

and the permissible bounds for a real-valued constant are:

-1.7976931348623157e+308 to +1.7976931348623157e+308

The result of an arithmetic expression involving mixed real and integer values will be a real value.

Updated