Syntax Guide
Learn how to compose queries that are based on and conform to Bosch Semantic Stack RQL.
Attribute names
An API that supports Bosch Semantic Stack RQL and can be queried by it, needs the attribute names (aka field names) of its entities (aka resources) to follow a certain syntax.
Attribute names that get used in select
, filter
, and sort
statements are restricted to the following characters:
Attributes can be nested by separating them using a dot .
as nesting separator.
The following table details some attribute name examples.
Example attribute name | Description |
---|---|
|
A simple attribute named 'name'. |
|
A simple attribute named 'id'. |
|
A simple attribute name containing underscores and numbers. |
|
Attribute names may start with an underscore (but why would you?). |
|
Invalid: attribute names must not start with numbers. |
|
A nested attribute: the 'street' child attribute is nested in the 'address' parent attribute. |
|
Invalid: attributes must not start with the nesting separator. |
|
Meaningless: the parser reads this but no action will follow as after the nesting separator no attribute is specified. |
Main operators
With Bosch Semantic Stack RQL, a query can use up to three operators:
-
select
-
filter
-
option
The following example represents the general form of a Bosch Semantic Stack RQL query string.
select=id,name&filter=ge(id,4711)&option=sort(+name,-description),limit(10,5)
The above query string means:
- select
-
Select the attributes
id
andname
. - filter
-
Filter for
id
attribute values that are greater than or equal to4711
. - option
-
Sort the results ascending by
name
and descending bydescription
. — Note that the attributes used for sorting (e.g.,description
) do not have to appear in the select operator.
Limit the returned results to 5 results, starting at result no. 10. — Note that the start of indices depends on a service’s implementation as some databases or library’s start counting at page 0 and some at page 1.
Select operator
The select
operator trims an API response down to only a given set of attributes.
That means, the data of any further attributes of an entity will not be included in the API response.
The general form of the select
operator string looks as follows:
select=attribute1,attribute2,attributeN
User-defined select can be requested via RQL for a root entity. The attributes names are separated by a comma. All child entities will then not be loaded. This means that response times can be significantly improved if only the requested information is returned.
Example: Load (select) only IDs and name (select) and do that only for the root entity.
select=id,name
Filter operator
The filter
operator trims an API response down to match only a given set of filter criteria.
That means, data not matched by the filter criteria will not be included in the API response.
The general form of the filter
operator string looks as follows:
filter={<filter expression>}
The value of the filter
operator is a filter expression that uses one of the following operators:
-
Comparison:
eq
,in
,ne
,gt
,ge
,lt
,le
,like
,likeIgnoreCase
-
Logical:
and
,or
,not
Example:
filter=and(like(hobbies.description,"?iking*"),eq(hobbies.name,"ships"))
A query containing the filter expression above would return results (e.g., entities that resemble persons) having a hobby with the name "ships" and where that hobby’s description contains "?iking*". That means, results could be "biking", "viking", "vikings", "vikingships", etc.
The following sections detail the operators that come with Bosch Semantic Stack RQL.
Comparison operators
Bosch Semantic Stack RQL supports the following comparison operators for usage with the filter
operator.
Note: A count()
operator to count all entities in an API response to the query is not yet implemented.
eq, ne
Data types:
For the provided <value>, these operators accept all literals, i.e., every common data type, including times, Boolean, null
, etc.
Operator expression | Description |
---|---|
|
Filters for entities where the value of the specified attribute equals the provided value. |
|
Filters for entities where the value of the specified attribute is not equal to the provided value. |
ge, le, gt, lt
Data types:
For the provided <value>, these operators accept no Boolean or null
.
Operator expression | Description |
---|---|
ge(<attribute>,<value>) |
Filters for entities where the value of the specified attribute is greater than or equal to the provided value. |
le(<attribute>,<value>) |
Filters for entities where the value of the specified attribute is less than or equal to the provided value. |
gt(<attribute>,<value>) |
Filters for entities where the value of the specified attribute is greater than the provided value. |
lt(<attribute>,<value>) |
Filters for entities where the value of the specified attribute is less than the provided value. |
in
Data types:
For the provided <array-of-values>, this operator accepts only pure lists, i.e., only floats, only strings, or only integers.
It does not support null
as a literal.
Operator expression | Description |
---|---|
in(<attribute>,<array-of-values>) |
Filters for entities where the value of the specified attribute is present in the provided array. |
Example:
|
Returns all entities that have an attribute named "twinCategory" containing values of either "Machine" or "Device". |
like, likeIgnoreCase
Data type:
For the provided <value>, these operators accept only strings.
Additionally, they also support wildcards:
-
Use
?
for a single undefined character. -
Use
*
for any number of undefined characters.
Operator expression | Description |
---|---|
|
Filters for entities where the value of the specified attribute matches the provided value – also in terms of capitalization, i.e., upper case or lower case. The provided value typically contains at least one of the following wildcards: |
|
Ditto. But here, the results' capitalization (upper case or lower case) is not required to match the capitalization used for the filter string of the provided value. |
Example:
|
Returns all entities with a description containing "my device", independent of the capitalization of the words. That means results also can contain "My device", "my Device", "My Device", "MY DEVICE", etc. |
Logical operators
Bosch Semantic Stack RQL supports the following logical operators for usage with the filter
operator.
Logical Expression | Description |
---|---|
|
Executes all the provided queries. |
|
The combination of the provided queries. |
|
Negates the provided query. |
Example:
|
Returns all entities with the "twinCategory" attribute’s value "Printer" and at least one label with name "Floor1". |
Data types
The values used to filter results can be of several data types, such as strings, times, numbers, Boolean, etc. While these data types are common data types, this section highlights relevant details for the use with Bosch Semantic Stack RQL.
Strings
Can be any Unicode (except Unicode escapes \u1234
).
The escaping rules of Bosch Semantic Stack RQL follow Java escaping rules closely.
Escape character is the backslash \
.
The following table lists possible escape sequences.
How to escape | What gets escaped |
---|---|
|
Escapes the backslash itself. |
|
Escapes a tabulator. |
|
Escapes a new line. |
|
Escapes a carriage return. |
|
Escapes a double quote. |
Times
The Bosch Semantic Stack RQL parser (and the corresponding model) supports time literals such as the OffsetDateTime
represented in a subset of ISO 8601.
Some less used features of ISO 8601 are not supported (and most likely will not be supported in the near future):
-
Reduced precision: giving a partial time such as
hh
orhh:mm
-
Fractional hours or minutes: ISO 8601 states that you can use fractions of the most precise time component (hour, minute, second). This is not supported by Bosch Semantic Stack RQL, which only supports a fixed precision including seconds.
Therefore, the following examples are valid ISO 8601 but not valid Bosch Semantic Stack RQL:
-
2007-12-03T10:15Z
(reduced precision—not supported) -
2007-12-03T10:15+4:27
(fractional time components—not supported)
Valid examples for Bosch Semantic Stack RQL are:2007-12-03T10:15:30.0123Z 2007-12-03t10:15:30+04:37
|
Integer numbers, real numbers, null
When using the Bosch Semantic Stack RQL parser, data types that come in with a query will be mapped to the corresponding Java data types.
The following table details how incoming RQL data types get parsed to Java data types.
Data type | Example | Mapping to Java data type |
---|---|---|
Integer number |
|
Gets parsed into the smallest fitting Java data type ( |
Real number |
|
Gets parsed into the Java data type |
|
|
Gets mapped to |
Option operator
The option
operator sorts and limits API responses.
That means, you can prevent an arbitrary order of your retrieved results.
With this user-defined sorting, clients are able and responsible for requesting data in the order that fits their needs.
Limit
and cursor
describe 2 pagination strategies and cannot be used together.
The general form of the option
operator string looks as follows:
option=sort(),limit(),cursor()
As an example, the option
string could look like this:
option=sort(-attribute1,+attribute2),limit(10,5)
Sorting
To sort the retrieved data, use the sort
operator as part of the option
operator.
option=sort([+-]attributeN)
The sort
operator sorts the data based on the specified attributes:
-
It starts sorting with the first attribute, then proceeds to the next etc.
-
To separate the attribute names that you require for sorting, use a comma.
-
For each attribute, you can specify whether to sort the results in ascending or descending order, indicating sort order by the + or - prefix.
-
For ascending sort order, use the + prefix.
-
For descending sort order, use the - prefix.
-
Example:
option=sort(-attribute1,+attribute2,[+-]attributeN)
In the example above, results will first be sorted in descending order for attribute1
, then will further be sorted in ascending order for attribute2
, and then ascending or descending for any more attributes that might be added.
Pagination
To control the pagination of the retrieved data, use the limit
or cursor
operator as part of the option
operator.
Only one of the two strategies can be used.
Limit is often used as offset pagination, where cursor is cursor pagination or also known as key set pagination.
Offset Pagination
option=limit(start,count)
The syntax is related to offset pagination.
That means the start
and count
parts in the string above conceptually stand for the following numbers:
-
start
specifies where to start fetching data, also known as offset -
count
indicates how many results to fetch per page
Example:
option=limit(10,5)
In the example above, results will start at result no. 10 and 5 results will be included in the API response.
Currently, only offset pagination is provided with Bosch Semantic Stack RQL.
Cursor Pagination
option=cursor(start?,limit)
The syntax is related to cursor pagination.
That means the start
and limits
parts in the string above conceptually stand for the following numbers:
-
start
specifies where to start fetching data, also known as cursor. If cursor is empty you will start at the beginning. -
limit
indicates how many results maximal to fetch. When there are more result, you will receive a new cursor for the next request.
Example:
option=limit("myCursor",10)
option=limit(100)