# Information Model QEL Queries
The continuous expansion of the platform necessitates support from various storage solutions. Query Expression Language (QEL) offers a custom, human-readable query representation to address this need. A significant advantage of QEL is that developers are not required to be familiar with the implementation details of the platform components or the specific language used for database communication (e.g., Gremlin, mongo expression syntaxes). Across most APIs in the platform, QEL provides a unified acceptance of boolean expressions, serving as a versatile where clause condition. The content on this page aims to provide developers with comprehensive information about QEL expressions supported in the Information Model, offering dedicated sections outlining supported syntax accompanied by illustrative examples.
# Comparison: QEL vs DSL vs Gremlin
- QEL - Query Expression Language:
- Supports human-readable boolean expressions representing where clause conditions.
- Employed in end-user requests for external communication.
- Applicable in filters and internally within the Condition header.
- DSL - Domain Specific Language:
- Custom syntax built atop the Gremlin traversal language.
- Offers more self-explanatory syntax compared to pure Gremlin.
- Utilized in the/query endpoint.
3 Gremlin Traversal Language:
- The actual query language comprehended by the graph database.
# DSL Usage & Benefits:
- Simplifies Gremlin's complex syntax: DSL makes Gremlin's syntax more accessible, specifically designed for use in the /query endpoint of the platform, making it the preferred choice for such operations. It can be customized for specific platform needs, enhancing the efficiency of query operations.
- Used for Querying ABB's Information Models-based objects.
- Popular for Self-Explanatory Syntax Needs: If the native Gremlin syntax seems too complex or less intuitive, DSL is a great alternative as it offers a more self-explanatory syntax.
# QEL Usage & Benefits:
- Ideal for representing 'where clause' conditions: QEL is ideal when you need to represent 'where clause' conditions in a format that is easily understood by humans. This feature is particularly useful for developers who may not be familiar with complex database query languages.
- Used for filtering specific schemas from ABB's Information Model's Definition Registry & Data Access APIs.
- Benefits users where filtering data is required, especially within the internal logic of the platform, particularly in the Condition header.
# Filters in Instance API
# Overview
Instance API has a few endpoints that offer filtering capabilities. The syntax of the filtering is defined by the Query Expression Language (QEL).
The filter value is a string parameter represented as a QEL expression and is supported by:
- type definitions query endpoint
- information model query endpoint
- data access warm path endpoints
Type Definitions and Information Models do not require filtering, while Data Access Warm Path requires a filter to be used with every request.
When applied, the filter acts upon requests as follows:
- The received QEL is parsed into an expression (same as
ability-conditionis received). - The final predicate contains the actual request concatenated with the and
operator, with a translated filter expression (and
ability-conditionheader if it exists).
# Information Model API
The filter as applied to information model endpoints appears as follows:
- GET /objects
- GET /objects/{objectId}/models/{modelId}/references
DSL Queries
Information Model objects can also be queried using the DSL, which is much more powerful than QEL.
# Functional Behavior
# Supported Grammar
IM QEL supported grammar:
expression =
"NOT" expression | expression ("AND" | "OR") expression | operand ( "=" | "!=" ) operand | operand "IN" ([literal ("," literal)*] | property) | property ("HAS" | STARTS_WITH" | "ENDS_WITH") stringLiteral | "(" expression ")"
where:
property and a literal can act as an operand.
Also note that literals can be defined as any of the primitives:
- boolean
- string
- null
# Property Names
Following are the top-level property names recognized by QEL grammar:
object model resource
- "objectId"
- "model"
- "type"
- "name"
- "tags"
- "ownerId"
- "tenantId"
reference resource
- "referenceId"
- "isHierarchical"
- "isContainment"
- "name"
NOTE
Properties for the object model are not supported in filtering references and vice versa.
# Supported Functionality Examples
NOT operator
- NOT (isHierarchical);
- NOT (model IN ['abb.ability.device', 'abb.ability.config'])
( AND | OR ) operators
- (model = 'abb.ability.device') OR (model = 'abb.ability.config')
- (tenantId = 'tenantOne') AND (ownerId = null)
( = | != ) operators
- type != 'type.definition.device'
- isHierarchical = false
- ownerId != null
IN ([literal ("," literal)*] | property) operator
- model IN ['abb.ability.device', 'abb.ability.configuration']
- 'tag1' IN tags
( HAS | STARTS_WITH | ENDS_WITH ) operators
- model STARTS_WITH 'abb'
- model ENDS_WITH 'device'
- model HAS 'ability'
# Examples of GET Requests with Filter
Acceptable
curl -X GET "https:../objects?filter=tenantId=' 92986908-22e6-4bbb-a009-5c3dd50feeb3'&limit=10" -H "accept: application/json"curl -X GET "https:../objects?filter=(model='abb.ability.device') AND tenantId='92986908-22e6-4bbb-a009-5c3dd50feeb3'&limit=100" -H "accept: application/json"curl -X GET "https:../objects/153d85bd-2e8c-4897-8f24-c69000008086/models/abb.ability.device/references?filter=isHierarchical=true AND isContainment=true" -H "accept: application/json"
Unacceptable
curl -X GET "https:../objects?filter=referenceId=' 92986908-22e6-4bbb-a009-5c3dd50feeb3'&limit=10" -H "accept: application/json"Why?
ReferenceId/isHierarchical/isContainment (references related top level property names) are not valid properties for object models QEL filtering.curl -X GET "https:../objects/153d85bd-2e8c-4897-8f24-c69000008086/models/abb.ability.device/references?filter=ownerId=' 123' and isContainment=true" -H "accept: application/json"Why?
"objectId"/"model"/"type"/"name"/"tags"/"ownerId"/"tenantId" (object model allowed top level property names) are not valid operands params for references QEL filtering.
# Type Definition Registry API
The filter as applied to type definition registry endpoints appears as follows:
- GET /modelDefinitions
- GET /modelDefinitions/{modelId}/types
- GET /definitions/alarms
- GET /definitions/events
Examples of QEL-supported filters for the third and fourth APIs.
- definitionId='somedefinitionid'
- "name = 'testAlarm' and 'baseAlarm@1.0.0' in baseDefinitions and 'testAlarm2' in tags"
- "definitionId = 'abb.ability.Alarm' and 'baseAlarm@1.0.0' in baseDefinitions"
# Functional Behavior
# Supported Grammar
IM QEL supported grammar:
expression =
"NOT" expression | expression ("AND" | "OR") expression | operand ( "=" | "!=" ) operand | operand "IN" ([literal ("," literal)*] | property) | property ("HAS" | STARTS_WITH" | "ENDS_WITH") stringLiteral | "(" expression ")"
where:
property and a literal can act as an operand.
Literals can be defined as any of the primitives:
- boolean
- string
- null
# Property Names
Following are the top-level property names recognized by QEL grammar:
model definition resource:
- "modelId"
- "name"
- "tags"
type definition resource:
- "model"
- "typeId"
- "name"
- "tags"
- "version"
NOTE
If version is not specified in the filter, the latest version of the type
definition is retrieved. If any version is included in the filter, the
version(s) from filter are retrieved
# Supported Functionality Examples
NOT operator
- model definitions: NOT (modelId IN ['abb.ability.device', 'abb.ability.configuration'])
- type definitions: NOT (model IN ['abb.ability.device', 'abb.ability.configuration'])
(AND | OR ) operators
- model definitions: name = 'Descriptive name' AND (modelId = 'abb.ability.device' OR modelId = 'abb.ability.configuration')
- type definitions: name = 'Descriptive name' and model = 'abb.ability.device' or typeId = 'type'
( = | != ) operators
- name != 'Descriptive name'
- typeId = 'type.Factory'
operand IN ([literal ("," literal)*] | property)
- modelId in ['abb.ability.device', 'abb.ability.configuration']
- 'tag1' in tags
# Examples of GET Requests with Filter
Acceptable
curl -X GET "https:../modelDefinitions/abb.ability.device/types?filter=(typeId = 'abb.processAutomation.sensors.smartSensorTag') OR (model = 'abb.ability.device')&limit=100&includeDeleted=false" -H "accept: application/json"curl -X GET "https:../modelDefinitions/abb.ability.device/types?filter='sensor' IN tags&limit=10&includeDeleted=false" -H "accept: application/json"curl -X GET "https:../modelDefinitions?filter=name in ['Device model', 'Configuration model'] or "isSensor" IN tags&limit=100&includeDeleted=false" -H "accept: application/json"
Unacceptable
curl -X GET "https:../modelDefinitions?filter=typeId='type.definition.sensor' &limit=100&includeDeleted=false" -H "accept: application/json"Why?
"typeId" is not a valid operand param for models QEL filtering.
# Examples of filters in query payloads
QEL grammar is capable of filtering by version = <exactVersion>. The filtering parameter can be used as follows:
typeId = 'abb.ability.my.type' AND version = '1.1.1'
typeId = 'abb.ability.my.type' AND version = '1.1'
typeId = 'abb.ability.my.type' AND version = '1'
typeId = 'abb.ability.my.type' AND version >= '1'
# Data Access API
The filter as applied to type definition registry endpoints appears as follows:
- POST /data/variables
- POST /data/alarms
- POST /data/events
The filter is part of the payload. See Data API Access Examples for more information.
# Functional Behavior
# Supported Grammar
IM QEL supported grammar:
expression =
"NOT" expression | expression ("AND" | "OR") expression | operand ( "=" | "!=" ) operand | operand "IN" ([literal ("," literal)*] | property) | property ("HAS" | STARTS_WITH" | "ENDS_WITH") stringLiteral | "(" expression ")"
where:
property and a literal can act as an operand.
Literals can be defined as any of the primitives:
- boolean
- string
- null
# Property Names
Following are the top-level property names recognized by QEL grammar:
variable resource:
- "objectId"
- "model"
- "variable"
- "timestamp"
- "value"
- "quality"
- "tenantId"
alarm resource:
- "objectId"
- "model"
- "alarm"
- "timestamp"
- "value", note that filtering is only possible on properties of primitive types (via the dot notation, i.e. value.foo.bar)
- "quality"
- "tenantId"
event resource:
- "objectId"
- "model"
- "event"
- "timestamp"
- "value", note that filtering is only possible on properties of primitive types (via the dot notation, i.e. value.foo.bar)
- "quality"
- "tenantId"
tenantId
Filtering by "tenantId" is possible only for telemetry data generated by devices. The telemetry generated using Publisher API does not have tenancy information included.
# Supported Functionality Examples
NOT operator
- NOT (variable = 'voltage') AND objectId='22ab830b-6fc6-4bf5-9579-8ae38088074a'
(AND | OR ) operators
- objectId = '22ab830b-6fc6-4bf5-9579-8ae38088074a' AND (variable = 'voltage' OR variable = 'current')
( = | != ) operators
- variable != 'voltage'
- objectId='22ab830b-6fc6-4bf5-9579-8ae38088074a' AND model != 'abb.ability.device'
operand IN ([literal ("," literal)*] | property)
- objectId = '22ab830b-6fc6-4bf5-9579-8ae38088074a' AND model in ['abb.ability.device', 'abb.ability.telemetry']
# Example Queries
Examples of queries that can be used for Info Model and Type Definition Registry endpoints are available here.
# Get All Object Models with a Specified objectID (all related models)
- objectId = '338af010-b8b7-48f1-9592-0b4d7b2dd0de'
# Get Models with a Specified Owner
ownerId = '8d6c3a3f-caad-4c34-8108-df66e77baf25'
ownerId = null
# Get All Models for a Specified Tenant
- tenantId = '92986908-22e6-4bbb-a009-5c3dd50feeb3'
# All Object Models with Two objectIds
- objectId IN ['064e84ab-33e3-4147-a3d0-9e9d6c7c83ef', '338af010-b8b7-48f1-9592-0b4d7b2dd0de']
# Tags
# IM
'device' IN tags AND 'referencing' IN tags
'device' IN tags AND not('referencing' IN tags)
'device' IN tags
# TDR
- 'device' IN tags
# Filtering Object Model by Types
objectId = '338af010-b8b7-48f1-9592-0b4d7b2dd0de' AND type IN ['type.configuration@1', 'type.structure@1']
objectId = '338af010-b8b7-48f1-9592-0b4d7b2dd0de' AND type != 'type.device@1'
type STARTS_WITH 'type.'
# Filtering by Model
See examples for filtering by type (above).
# Filtering References by Name
name = 'connected'
name != 'connected'
name HAS 'conn'
# Filtering References by hierarchical/containment
isHierarchical = true
isContainment = false
Filtering by referenceId is also possible, but the same result can be achieved
by using a direct endpoint.