Operators
An operator's syntax will be described using placeholders. Those are intended to be replaced by any valid iteraQL expression that meets their specification. The placeholders are:
Placeholder | Meaning |
---|---|
%BB% | a building block, i.e. any iteraQL statement that produces a (synthetic) building block |
%sBB% | a stand-alone building block |
%aBB% | an associative building block |
%R% | a relation, i.e. any iteraQL statement that produces a (synthetic) relation |
%sR% | a self-referencing relation |
%P% | a property, i.e. any iteraQL statement that produces a (synthetic) property |
%PREDICATE% | a predicate |
Or any combination of placeholders, for example %BB | R% standing for either a building block or a relation.
Join or "/"-operator
Summary
Effect: | Combines two relations to a single one. |
---|---|
Input: | Relation, relation |
Output: | Relation |
Syntax
%R% / %R%
Explanation
The join operator is the simplest and one of the most frequently used operators available in iteraQL. This operator takes two relations and produces a new relation by “sticking” them together. If building block A has a relation to building block B called ab and building block B has a further relation bc to building block C, the join operator by ab/ac will result in a relation between building block A and building block C.
The join operator is distinguished from the others since it doesn’t require any keyword while its grammar consists of a single "/". However, the user might be aware that not every use of a "/" corresponds to the usage of the join operator, as the "/" character is as well used to reference to a building block's relation and in fact the abstract example above would be "A/ab/bc", where the first "/" is not a join operator but just the reference to a relation of A, whereas the second one is. (In fact, this sophisticated distinction of the use of "/" should never produce any irritations as its intuitive use should produce the wanted results.)
Moreover, the join operator is transitive, which means that it can be applied to an arbitrary number of relations. If there was a fourth building block D and a relation cd from C to D, "A/ab/bc/cd" would return the according relation from A to D. (This transitive usage also follows from the ability to concatenate operators as the output is a relation and hence can be used as input for a further join operator.)
Filter or "[]"-operator
Summary
Effect: | Reduce a building block's instances according to a filter |
---|---|
Input: | Building block, predicate |
Output: | Building block with the same relations and properties as the input building block |
Syntax
%BB% [ %PREDICATE% ]
Explanation
Next to the join operator, one of the most frequently used ones is the filter operator.
Given a building block and a predicate, it produces a filtered building block with the same features (i.e. relations and properties) as the original one but only possesses the instances of the original one which satisfy the predicate. Therefore, it creates a new building block by taking a building block and removing selected instances of it.
Objectify
Summary
Effect: | Transform a property into a building block |
---|---|
Input: | Property |
Output: | building block with the relation "\isValueOf" |
Syntax
.objectify( %P% )
Explanation
The objectify operator is a rather sophisticated one, as it takes a property and transforms it to a synthetic building block with a relation "isValueOf" and no further properties nor relations. For each different value of the property that has been given to at least one of the input building block's instances, an instance of the new building block is created which is related via _/isValueOf to all instances of the input building block with this value.
Nullify
Summary
Effect: | Enhances a building block with an artificial "null" instance such that formerly unrelated instances are related to it. |
---|---|
Input: | Building block |
Output: | Building block with the same properties and relations as for the input |
Syntax
%BB%.nullify()
Explanation
The nullify operator for building blocks enhances a building block by an artificial "null" instance that extends all of the building block's relations in a certain way: Consider A and B to be two different building blocks where A has a relation b to building block B. Now A.nullify() is the building block generated by the nullify operator and having the relation b to building block B. However, all instances of B which were not related to any instance of A by A/b are now related to the null instance of A.nullify().
Nullify for Relations
Summary
Effect: | Enhances a relation by relating all instances of the destination building block to an artificial "null" instance of the target building block. |
---|---|
Input: | Relation |
Output: | Relation to the same building block as the input |
Syntax
.nullify( %R% )
Explanation
The nullify operator for relations extends a given relation by relating all instances of the destination building block to an artificial "null" instance of the target building block. Consider A and B to be two different building blocks where A has a relation b to building block B. Now A.nullify(/b) is the relation generated by the nullify operator and establishes the same relation from A to B as _ /b_ did, but furthermore relates all instances of A that were not related to any instance of B by A/b to an artificial null instance of B.
With relations, the target building block is extended by a null instance, whereas with building blocks the nullify operator extends the destination instance (meaning itself) with respect to all its relations.
Unfold
Summary
Effect: | Summarizes all levels of a self-referencing relation to a single one. |
---|---|
Input: | Self-referencing relation |
Output: | Self-referencing relation to the same building block as the input one |
Syntax
.unfold( %sR% )
Explanation
The unfold operator takes a self-referencing relation and summarizes all of its levels by "unfolding" them to a single one. As the input relation is self-referencing, it relates the building block to itself and therefore the target building block of this self-referencing relation must have itself an identical self-referencing relation - by repeating this procedure one obtains different levels of a self-referencing relation. Merging the different levels of this self-referencing relation into a single one provides the output of the unfold operator.
The most commonly used self-referencing relation might be /children. Considering that children of a building block may have their own children, the /children relation might be considered to be of the 2nd level. The .unfold(/children) operation establishes a single relation from a building block to the children of first, and moreover to of all possible levels.
Note that this works with "circle" relations as well. For example, if building block A has a relation /ab to building block B having a relation bc to building block C having a relation ca to building block A, then ab/bc/ca is a self-referencing relation of A and therefore .unfold(/ab/bc/ca) is a valid iteraQL statement.
foldLevel
Summary
Effect: | Returns the foldLevel with respect to a self-referencing relation, i.e. the building blocks position in the hierarchical structure induced by the relation. |
---|---|
Input: | Self-referencing relation |
Output: | Number property |
Syntax
foldLevel( %sR% )
Explanation
The foldLevel operator returns the level of a building block with respect to a self-referencing relation's hierarchical structure. Given a self-referencing relation, the foldLevel of each instance of the building block is given by counting the number of times this relation can be repeatedly applied until an instance is reached which is not connected to any further one via the given relation. As an abstract example, consider the building block A having the self-referencing relation /a instances "inst A start", "inst A middle" and "inst A end" where /a connects "inst a start" with "inst a middle" and the latter with "inst a end". The foldLevels with respect to /a of "inst A basic", "inst A middle" and "inst A end" are therefore 2, 1 and 0, respectively. A more precise example can be found below.
Note that counting starts at "0", meaning an instance not related to any other is considered having foldLevel 0.
The foldLevel operator should be used only with relations what are looking like braches on a tree. It should not be used for relations which are DAG or have cycles. This restriction applies to the actual data, not to the structure definition. In effect, one could apply the foldLevel operator to a successor-predecessor relation if it only consists of trees. To be on the safe side, it is recommended to use the foldLevel operator only for statically tree-like relations, e.g., parent-children.
Expand
Summary
Effect: | Expands a building block with instances gained via a self-referencing relation. The building block is filtered in most cases. |
---|---|
Input: | Self-referencing relation |
Output: | Building block is expanded by instances reachable by the self-referencing relation |
Syntax
.expand( %sR% )
Explanation
The expand operator extends a building block by all instances which can be reached via a self-referencing relation. Obviously, this only seems reasonable if the building block has been filtered before, as otherwise it would already possess all instances in LUY.
Consider building block A having the property name and a self-referencing Relation /a. Assuming bulding block A having the instances "inst B #1","inst B #2" and "inst C #1" as well as "inst D #1" which is a child of "inst B #1". Then A[ @name.constains("B") ].expand(/children) gives the building block with instances "inst B #1" "inst B #2" (as both have a "B" in their names) and "inst D #1" (added by the expand operator).
Power
Summary
Effect: | Creates a new building block with a single instance that summarizes all instances of the input building block. |
---|---|
Input: | Building block |
Output: | Building block without properties and with exactly one relation "/isContainer" and exactly one instance that is related via "/isContainer" to all instances of the input building block. |
Syntax
%BB%.power()
Explanation
The power operator provides a building block which has a single instance connected to all instances of the given one. It therefore produces a new (very synthetic) building block from a given building block, which does not inherit any relations or properties from the input building block but possesses a single relation /isContainer and a single instance that is then related to all instances of the input building block via /isContainer.
This operator might be helpful whenever one needs to take all building blocks instances into consideration at once.
Count
Summary
Effect: | Counts the number of related building blocks or set values of a property, respectively |
---|---|
Input: | Relation or property |
Output: | Number |
Syntax
count( %R | P%)
Explanation
The count operator may be applied to a relation or a property. It counts the number of related instances via a relation or the number of set values of a property, respectively.
View
Summary
Effect: | Projects a property of a related building block to the building block of interest |
---|---|
Input: | Relation and property |
Output: | Property |
Syntax
view( %R% %P% )
Explanation
Given a relation and a property of the building block targeted by the relation, the view operator projects this property to the original building block. If the relation connects one instance of the original building block to several instances of the destination building block, all property values of those instances are projected as a multi-valued property. In an abstract example, consider the building block A connected via the relation /ab to the building block B that has the property @p. Then view( /ab @p) returns a property of A where each instance of A possesses all values of @p which the related instances of B possess.
Predicates and predicate-defining operators
Predicates are used to make selections of a building block's instances.
Working with predicates
A single predicate may be used by simply placing it in the square brackets of the filter-operator's syntax.
Negation of a predicate
A predicate may be negated by placing a "!" in front of it. By taking the original predicate this will turn every "yes" into a "no" label and vice versa.
Combining several predicates
Several predicates may be combined using "&" or "|" (meaning or).
"&"-combination
Two predicates may be combined via "&", meaning an instance of the building block must be labelled by both predicates with a "yes" to obtain a "yes" of the resulting predicate. Note that therefore the result of the use of "&" between two predicates provides itself a single predicate (that may be used further just as any other predicate). Furthermore, "&" is symmetric, meaning that the order of the two predicates to be combined does not matter.
"|" (or)-combination
Two predicates may be combined via "|", meaning an instance of the building block must be labelled by at least one of the two predicates with a "yes" to obtain a "yes" of the resulting predicate. Just as seen for "&", the result of the use of "|" between two predicates provides itself a single predicate and "|" is symmetric meaning that the order of the two predicates to be combined does not matter.
Combining more than two predicates
As seen above, the result of combining two predicates via "&" or "|" provides a predicate that may be combined itself with another predicate. However, when using "&" and "|" combinations at the same time, it might be important to state the order in which these combinations are intended. This can be achieved using brackets "(...)". Any predicate may be placed into brackets without changing its meaning or validity. By placing a predicate resulting from a combination of two other predicates into brackets one forces iteraQL to first achieve the predicate inside the brackets and then execute any further operation with this result. Whenever "&" and "|" are used simultaneously, the use of brackets is highly recommended. If no brackets are used, iteraQL will execute the combinations in the order in which they are written in the query.
When negating combined predicates, the use of brackets is necessary because iteraQL has no dedicated operator precedence and hence the ! (NOT) operator does not have a higher rank than the & (AND) and | (OR) operators.
Comparison operators
This section presents the different comparison operators available for the iteraQL filter criteria for each supported data type. Comparisons may be made with numeric, string or date attributes. To obtain a valid predicate, make sure both sides that are to be compared are of the same nature.
Numeric comparison
Syntax | Meaning |
---|---|
arg1 = arg2 | Numeric equality between two arguments |
arg1 != arg2 | Numeric inequality between two arguments |
arg1 < arg2 | The first argument is smaller than second argument |
arg1 <= arg2 | The first argument is smaller than or equal to second argument |
arg1 > arg2 | The first argument is greater than the second argument |
arg1 >= arg2 | The first argument is greater than or equal to the second argument |
String comparison
Note: All string comparison operators are case-insensitive.
Syntax | Meaning |
---|---|
arg1 = arg2 | String equality between the arguments |
arg1 != arg2 | String inequality between the arguments |
arg1.contains(arg2) | The value of the property represented by arg1 contains the string or value of property represented by arg2 |
arg1.beginsWith(arg2) | The value of the property represented by arg1 begins with the string or value of property represented by arg2 |
arg1.endsWith(arg2) | The value of the property represented by arg1 ends with the string or value of property represented by arg2 |
Date comparison
Note: Date values should be given in quotes to ensure correct recognition, e.g., "09/01/12" instead of 09/01/12.
Syntax | Meaning |
---|---|
arg1 = arg2 | The two arguments represent the same date with day accuracy |
arg1 != arg2 | The two arguments represent different dates with day accuracy |
arg1 < arg2 | The date represented by arg1 comes before the date represented by arg2 |
arg1 <= arg2 | The date represented by arg1 comes before, or is the same as the date represented by arg2 |
arg1 > arg2 | The date represented by arg1 comes after the date represented by arg2. |
arg1 >= arg2 | The date represented by arg1 comes after, or is the same as the date represented by arg2. |
Date ranges
The complete string with date range values should be written in quotes to ensure correct recognition, e.g., "09-01-12;10-01-12" instead of 09-01-12;10-01-12.
Syntax | Meaning |
---|---|
fromDate;toDate | The start and end date for a range specification. |
Comparison operators on multi-valued properties
It might happen that a multi-valued property is one of the two sides of a comparison. In this case, the statement remains valid if the single values of both sides are still of the same kind, meaning both numeric, a string or a date.
Multi-valued left-side
If the left side in a comparison operator is a multi-valued property, the predicate returns a "yes" label if at least one value in the list of the left side obtains a "yes" from the comparison.
Multi-valued right-side
If the right side in a comparison operator is a multi-valued property, the predicate returns a "yes" label only if all values in the list of the right side obtain a "yes" from the comparison.
Contains
Summary
Effect: | States whether a text contains a given text-string |
---|---|
Input: | Text property |
Output: | Predicate |
Syntax
%P%.contains( "%TEXTSTRING%" )
Explanation
The “contains” operator returns a predicate that selects instances of the affected building block by checking whether or not the given property contains the respective text-string.
Begins with
Summary
Effect: | States whether a text begins with a given text-string |
---|---|
Input: | Text property |
Output: | Predicate |
Syntax
%P%.beginsWith( "%TEXTSTRING%" )
Explanation
The “begins with” operator returns a predicate that selects instances of the affected building block by checking whether the given property begins with the respective text-string.
Ends with
Summary
Effect: | States whether a text ends with a given text-string |
---|---|
Input: | Text property |
Output: | Predicate |
Syntax
%P%.endsWith( "%TEXTSTRING%" )
Explanation
The “end with” operator returns a predicate which selects instances of the affected building block by checking whether the given property ends with the respective text-stringt.