Query language
The query language is the core of any database machine. evitaDB has chosen a functional form of the language instead of a SQL-like language, which is more consistent with how it works internally and, most importantly, much more open to transformations.
This language is expected to be used by human operators, at the code level the query is represented by a query object tree, which can be constructed directly without any intermediate string language form (as opposed to the SQL language, which is strictly string typed).
- header: defines the queried entity collection (it's mandatory unless the filter contains constraints targeting globally unique attributes)
- filter: defines constraints that limit the entities returned (optional, if missing, all entities in the collection are returned)
- order: defines the order in which entities are returned (optional, if missing entities are sorted by primary integer key in ascending order)
- require: contains additional information for the query engine - such as pagination settings, requirements for completeness of returned entities, and requirements for calculation of accompanying data structures (optional, if missing, only primary keys of entities are returned).
Grammar
The grammar of a query is as follows:
Or more complex one:
Syntax format
- argument:type,specification
- argument represents an argument of a particular type, for example: argument:string represents a string argument at a particular position.
- constraint:type,specification
- constraint represents an argument of constraint type - the supertype (filter/order/require) of the constraint is always specified before the colon, for example: filterConstraint:any;
after the colon, the exact type of allowed constraint is listed, or the keyword `any' is used if any of the standalone constraints can be used
Variadic arguments
If the argument can be multiple values of the same type (an array type), the specification is appended with a special character:
- * (asterisk)
- denoting the argument must occur zero, one, or more times (optional multi-value argument).
- + (plus)
- denoting the argument must one, or more times (mandatory multi-value argument).
Example of variadic arguments
- argument:string+
- argument at this position accepts an array of that has to have at least one item
- argument:int*
- argument at this position accepts an array of and may have zero or multiple items
- filterConstraint:any*
argument at this position accepts an array of any standalone filter constraints with zero or more occurrences
Mandatory arguments
Combined arguments
Example of combined arguments
- filterConstraint:(having|excluding)
- either having or excluding, or none, but not both, and no filtering constraint of other type is allowed
- filterConstraint:(having|excluding)!
- either with or exclude filter constraint, but not both, and not none, but no other filter constraint is allowed
- filterConstraint:(having|excluding)*
- either having or excluding a filter constraint, or both, or none, but no other filter constraint is allowed.
- filterConstraint:(having|excluding)+
- either having or excluding a filter constraint, or both, but at least one of them and no filter constraint of other type is allowed
Constraint naming rules
To make constraints more understandable, we have created a set of internal rules for naming constraints:
- the name of the entity should be in a form (tense) that matches the English query phrase: query collection ..., and filter entities by ..., and order result by ..., and require ...
- the query should be understandable to someone who is not familiar with evitaDB's syntax and internal mechanisms.
- The constraint name starts with the part of the entity it targets - i.e., entity, attribute, reference - followed by a word that captures the essence of the constraint.
- If the constraint only makes sense in the context of some parent constraint, it must not be usable anywhere else, and might relax rule #2 (since the context will be apparent from the parent constraint).
Generic query rules
Data type conversion
Array types targeted by the constraint
Header
Filter by
Filtering constraints allow you to select only a few entities from many that exist in the target collection. It's similar to the "where" clause in SQL. Currently, these filtering constraints are available for use.
Logical constraints
Logical constraints are used to perform logical operations on the products of child functions:
Constant constraints
Constant constraints directly specify the entity primary keys that are expected on the output.
Localization constraints
Comparable constraints
Comparable constraints compare the constants passed as arguments with a specific attribute of an entity, and then filter the resulting output to only include values that satisfy the constraint.
- attribute equals
- attribute greater than
- attribute greater than, equals
- attribute less than
- attribute less than, equals
- attribute between
- attribute in set
- attribute is
String constraints
Range constraints
Price constraints
Price constraints allow filtering entities by matching a price they posses:
Reference constraints
Reference constraints allow filtering of entities by existence of reference attributes specified on their references/relationships to other entities, or a filtering constraint on the referenced entity itself:
Hierarchy constraints
Hierarchy constraints take advantage of references to a hierarchical set of entities (forming a tree) and allow filtering of entities by the fact that they refer to a particular part of the tree:
Special constraints
Special constraints are used only for the definition of a filter constraint scope, which has a different treatment in calculations:
Order by
Order constraints allow you to define a rule that controls the order of entities in the response. It's similar to the "order by" clause in SQL. Currently, these ordering constraints are available for use:
- entity primary key in filter
- entity primary key exact
- entity primary key natural
- attribute set in filter
- attribute set exact
- attribute natural
- price natural
- reference property
- entity property
- entity group property
- random
Require
Requirements have no direct parallel in other database languages. They define sideway calculations, paging, the amount of data fetched for each returned entity, and so on, but never affect the number or order of returned entities. Currently, these requirements are available to you:
Paging
Paging requirements control how large and which subset of the large filtered entity set is actually returned in the output.
Fetching (completeness)
- entity fetch
- entity group fetch
- attribute content
- associated data content
- price content
- reference content
- hierarchy content
Hierarchy
Hierarchy requirements trigger the calculation of additional data structure that can be used to render a menu that organizes the entities into a more understandable tree-like categorization:
- hierarchy of self
- hierarchy of reference
- from root
- from node
- children
- siblings
- parents
- stop at
- distance
- level
- node
- statistics
Facets
Facet requirements trigger the computation of an additional data structure that lists all entity faceted references, organized into a group with a calculated count of all entities that match each respective facet. Alternatively, the summary could include a calculation of how many entities will be left when that particular facet is added to the filter:
Histogram
Histogram requests trigger the calculation of an additional data structure that contains a histogram of entities aggregated by their numeric value in a particular attribute or by their sales price:
Price
The price requirement controls which form of price for sale is taken into account when entities are filtered, ordered, or their histograms are calculated:
Telemetry
The telemetry requirements trigger the calculation of additional telemetry data for looking under the hood of the database engine: