EliasDB query language ====================== EliasDB query language (EQL) is a query langugage to search nodes in a partition of the graph database. Its syntax is designed to follow natural language supporting complex graph queries while keeping simple queries simple. A simple EQL query has the following structure: ``` get where ``` It reads: "Get all graph nodes of a certain node kind which match a certain condition". The condition is evaluated for each node from the specified kind. For example to get all `Person` nodes with the name `John` you could write: ``` get Person where name = John ``` The result of this query is a table listing all data store nodes which have a node attribute name with the value John. Where clause ------------ A where clause supports the following operators: - Standard boolean operators: `and, or, not` - Standard condition operators: `=, !=, >, <, >=, <=, in, notin, contains, beginswith, endswith, containsnot` - Standard arithmetic operators: `+, -, *, /`` - Integer operations: `//` (integer division), `%` (modulo) - Regular expression operator: `like` Operators can be combined. Expressions can be segregated using parentheses. Each where condition should end in a boolean value. List operators such as `in` and `notin` operate on sequences of values which can be declared with square brackets e.g. `[1,2,3]`. - Where clauses also support the following constants: `true, false, null` To explicitly define if a value represents a literal or a name of a node or edge attribute it is possible to prefix it with either `attr:` for a node attribute name, `eattr:` for an edge attribute name or `val:` for a literal. In the majority of cases however the query interpreter will determine the right meaning. The precedence is: node attribute, edge attribute, literal value. EQL supports nested object structures on node attributes. A node value of `{ l1 : { l2 : { l3 : 123 } } }` can be queried as: ``` .l1.l2.l3 = 123 ``` If the actual attribute name contains a dot then the `attr:` prefix must be used. Traversal blocks ---------------- For the majority of useful queries it will be necessary to traverse the graph. Relationships between nodes can be matched with traversal specifications. A traversal specification has the following form: ``` ::: ``` All components of a traversal specification are optional. A traversal of all relationships can be expressed with: ``` ::: ``` Traversal expressions in a query are defined as block expressions: ``` get where traverse where traverse where end end ``` Traversal expressions define which parts of the graph should be collected for the query. Reading from top to bottom each traversal expression defines a traversal step. Each traversal step will add several columns to the result if no explicit show clause is defined. Show clause ----------- To control which data will be displayed in the final result it is possible to define a show clause. A show clause explicitly states which columns should be displayed in the result table. ``` get where traverse where traverse where end end show , , ... ``` The data can be defined by traversal position, as attribute name or as node/edge kind with attribute name. Examples: ``` 1:n:key - Display the key of the start nodes 2:e:name - Display the name of the relationship from the 1 traversal step Person:name - Display the name of the first defined Person node from the query name – Display the name of the first defined node which has a name attribute ``` With clause ----------- Operation which need to be applied once all rows of the result have been fetched can be defined in the with clause. If a with clause is defined it is always the last clause in a query. ``` get show with , , ... ``` The following operations are possible: - ordering - Order a column (e.g. `ordering(ascending Person:name)` ) Available directives: `ascending, descending` - filtering - Filter a column (e.g. `filtering(unique 2:e:name)` ) Available directives: `unique` (column will only have unique values), `unique count` (column will show unique values and a count of how many values were encountered), `isnotnull` (column will only contain not null values) - `nulltraversal` – Only includes rows in the result where all traversals steps where executed (i.e. do not include partial traversals) Available directives: `true, false` Functions --------- Functions can be used to construct result values. A function can be used inside a where clause and inside a show clause. All function start with an `@` sign. Functions for conditions: ``` @count(, ) - Counts how many nodes can be reached via a given spec from the traversal step of the condition. Can optionally have a condition string which limits the traversal. ``` ``` @parseDate(, ) - Converts a given date string into an unix time integer. The optional second parameter is the parsing layout stated as reference time (Mon Jan 2 15:04:05 -0700 MST 2006) - e.g. '2006-01-02' interprets -- strings. The default layout is RFC3339. ``` Functions for the show clause: ``` @count(, , ) - Counts how many nodes can be reached via a given spec from a given traversal step. Can optionally have a condition string which limits the traversal. ``` ``` @objget(, , ) - Extracts a value from a nested object structure. ```