givenName = "John" and familyName = "Doe"
Introduction to midPoint Query Language
This document provides introduction to the midPoint Query Language. Some details are omitted, and there are some simplifications for clarity.
After completing this document, reader should be able to apply midPoint Query Language in configuration. We encourage to test the queries using the query playground, which provides convenient and interactive environment for experimenting with queries.
Language Description
The midPoint Query Language is designed to allow specification of a complex queries. Yet the basic structure of the language is relative simple and easy to understand.
The query is a combination of a filter with additional parts such as paging and sorting. It is the filter part that attracts most attention.
Simple filter usually take the usual form of item filterName value
triple, where:
- item
-
Item Path - specifies the searchable item on which should be the filter applied.
- filterName
-
Name of filter to be used.
- value
-
Value literal or Item Path which should be matched according filter specification. String needs to be enclosed in quotes (
'
) or double-qoutes ("
)
Some examples of valid filters are:
-
fullName = "John Doe"
-
givenName startsWith "J"
-
activation/effectiveStatus = "enabled"
Item Path
The item on which data are filtered is specified by item path. In its simplest form it is a name of object property, or names of items and containers separated by slashes. Such as:
-
fullName
-
activation/administrativeStatus
-
attributes/uid
Filter Name
Item path is followed by filter name or its alias, which specifies which filtering condition should be used.
Comparison filters
Following tables summarizes common property filters:
Name | Alias | Description |
---|---|---|
|
|
Matches if any item is equal to value |
|
!= |
Matches if item is different from value |
|
|
Matches if item is smaller than value |
|
|
Matches if item is smaller or equal to the value |
|
|
Matches if item is greater than value |
|
|
Matches if item is greater or equal to value |
familyName = "Doe"
-
equals filter - All users with familyName Doe
name != "Administrator"
-
not equals filter - Everyone except administrator
activation/validTo < "2022-01-01"
-
less filter - All users which will not be valid after 2021
Comparison filters also supports item path on right side of filter.
For example activation/validFrom > activation/validTo
should return all objects with incorrectly set activations (activation start is after activation end).
Matching rules
Comparison filter can be even more specified by definition of matching rule in the filter.
The syntax of matching rule in query is: filter[matchingRuleName]
givenName =[origIgnoreCase] "Adam"
-
query matches all 'Adam', 'adam' or 'ADAM' in givenName
emailAddress endsWith[stringIgnoreCase] "@test.com"
-
query matches user with email address ending with specific domain.
See different matching rules in the examples above. There are different matching rules defined for PolyStringType (givenName) and strings (emailAddress). List of all matching rules is defined in matching rules page.
String filters
Following table summarizes additional filters that can be applied on string and polystring values.
Name | Description |
---|---|
|
Matches if item starts with specified string. |
|
Matches string property if it contains specified substring. |
|
Matches string property if it ends with specified substring. |
|
Performs full text search. Item path must be dot (.) |
Value
Value is usually a string literal, enclosed in double quotes. However, value may take various forms. For example, it may be a path of another item, e.g. in case when the query compares two items. The value may be also quite complex.
The exact form of the value part of the filter depends on the operator and type of the value.
Querying values of different types
The exact syntax of queries for values of different types is described in the following table:
Type | Query | Note |
---|---|---|
boolean |
|
Boolean values do not need quotes. Allowed values are |
string |
|
String values are enclosed in quotes (') or double quotes ("). |
PolystringType |
|
Values of PolystringType are enclosed in quotes (') or double quotes ("). |
int |
|
Number values do not need quotes. Only common property filters (=,>, ..) are defined for number types. |
float |
|
Number values do not need quotes. Only common property filters (=,>, ..) are defined for number types. |
dateTime |
|
DateTime values are enclosed in quotes (') or double quotes ("). It can be compared as dates or date and time - written in format of ISO-8601. |
|
While comparing time values. DateTime values entered without timezone are considered to be in the same timezone as running midPoint. |
|
|
As datetime values contain exact time value up to milliseconds you need to compare dates as intervals. See examples. |
|
ObjectReferenceType |
|
Object references are queried using |
QName |
|
QName values (relation in this example) are entered into query without quotation marks. Do not use them. |
|
QNames may use namespaces. The namespaces are not necessary in the query - of course, if the values don’t collide. So, both queries with |
Logical Filters
Logical filters are used to combine several sub-filters into one filter or to negate filter.
There is a usual set of logic operators:
Operator | Example | Description |
---|---|---|
|
|
All subfilters must be true. |
|
|
Any of the subfilters is true. |
|
|
Logical negation. Not prefixes filter name (as seen in example). |
You can use round brackets to group logical statements into more readable form.
familyName = "Doe" and (givenName = "John" or givenName ="Bill")
Object selection
Midpoint performs queries over defined set of objects. In GUI, the set is defined by actually opened view.
In configuration, the object type must be explicitly specified for the query.
Not within the query itself.
See the configuration snippet below. The query will select User
with name "XYZ".
<activity>
<work>
<recomputation>
<objects>
<type>UserType</type>
<query>
<q:filter>
<q:text>name = "XYZ"</q:text>
</q:filter>
</query>
</objects>
</recomputation>
</work>
</activity>
Advanced filters
matches filter
matches
filter operates on the container or structured value and specifies conditions that must be met by a single container value.
It is in form of itemPath matches (subfilter)
, where subfilter (and item paths) are relative to the container, for example assignment/validTo < "2022-01-01"
is same as assignment matches (validTo < "2022-01-01")
.
The subfilter
is any supported filter, where paths are relative to container
and allows us to specify multiple conditions (joined using Logical Filters), which must be met by container value.
Example of matches filter:
activation matches ( validFrom > "2022-01-01" and validTo <"2023-01-01" )
For filters matching multiple properties of multi value containers (such as If these multiple criteria must be met by one container value you must use The filter |
inOid filter
midPoint query allows querying objects by its oid using inOid
filter.
The inOid queries is triplet consisting of object representation, inOid
filter and list of oid values enclosed in brackets.
The midPoint object is represented by .
(dot character).
Example of querying one specific object by its OID:
. inOid ("00000000-0000-0000-0000-000000000702")
Example of querying 2 specific objects by their OID:
. inOid ("eb21455d-17cc-4390-a736-f1d6afa82057", "87e048ae-6fcf-47bb-a55e-60acb8604ead")
Reference Filters
Reference filters allows to match on references themselves using
matches
filter on properties of referenced objects using dereferencing operator (@
).
You can also perform inverse queries using referencedBy
filter to search
for object by properties of it’s referencer (e.g. search roles by properties of its members).
matches filter in references
Reference itself is structured value, which contains target oid, target type and relationship type.
You can use matches
filter with nested subfilters to target these properties of object reference:
- oid
-
Exact match of target oid (UUID as string). Example:
assignment/targetRef matches (oid = efaf89f4-77e9-460b-abc2-0fbfd60d9167)
- relation
-
Matches any reference with specified relation (QName). Example:
roleMembershipRef matches (relation = manager)
- targetType
-
Matches any reference with specified target type (QName). Example:
roleMembershipRef matches (targetType = OrgType)
It is possible to match on any combination of these three properties of reference,
but only equals
and and
filter are supported.
roleMembershipRef matches ( oid = "bc3f7659-e8d8-4f56-a647-2a352eead720" and relation = manager and targetType = OrgType )
If you need to query referenced objects of specified type you must use targetType keyword. You can see it in example above. |
Dereferencing
Dereferencing allows to write filter condition which is executed on referenced object.
Dereferencing is done using @
special character in item path after reference, item path assignment/targetRef/@
points to object referenced by targetRef instead of targetRef itself.
This allows you to continue path with properties of referenced objects such as
assignment/targetRef/@/name
- which means name
of assigned object.
For example, this enables us to search for users with assigned role by role name instead of oid. (but it is executed a bit slower, since we need to dereference objects).
assignment/targetRef/@/name = "Superuser"
- matches any user who is directly assigned role of superuser.
To match also users, who are indirectly assigned role, you should use roleMembershipRef instead of assignment/targetRef .
|
If you need to match referenced object on multiple properties you should use matches filter.
|
Dereferencing inside reference matches filter
This feature is currently supported in midPoint native repository only |
If user wants to match on properties of reference itself and also on properties of it’s target
it is possible now, using dereferencing inside reference matches
filter.
In order to match on target you can use dereferencing and matching: @ matches (…)
.
Business Role
archetypeassignment/targetRef matches ( (1) targetType = RoleType (2) and relation = manager (3) and @ matches ( (4) archetypeRef/@/name = "Business Role" (5) ) )
1 | We are matching references in assignment/targetRef |
2 | Type of referenced target should be RoleType |
3 | Users relation to assigned role is manager |
4 | We dereference target and match on its properties |
5 | Name of role archetype should be Business Role . This is done by dereferencing archetypeRef using @ in item path. |
referencedBy filter
referencedBy
filter allows you to find object based on properties on objects, which
reference it. Since object as whole is referenced the item path
In order to use referencedBy
filter you must also specify type
of objects, which references it,
and path
of object reference, which is used for reference (e.g. assignment/targetRef
or inducement/targetRef
)
The short query syntax is:
. referencedBy ( (1) @type = UserType (2) and @path = assignment/targetRef (3) and name = "Administrator" (4) )
1 | . referencedBy filter name |
2 | @type - required, special filter property which specified type of objects which should be considered in evaluation of filter. In this case we are interested in users. |
3 | @path - required, special filter property which specifies which Object reference should be used in filter, in this case we are interested in directly assigned roles (assignment/targetRef ) |
4 | Filter which referencing object must match, in this case the name of referencing object must be Administrator . |
ownedBy Filter
Filter is currently supported in midPoint native repository only |
ownedBy filter allows for matching indexed containers based on properties of their parent (owning object or container).
The syntax is similar to referencedBy. ownedBy filter can only be applied on self path (.
). The properties of ownedBy filter are:
- type
-
(Required) Type of parent / owner.
- path
-
(Optional) Name / location of container inside parent.
- filter
-
(Optional) Filter, to which parent needs to conform, filter is explicit element in XML/YAML/JSON. In midPoint query any filter which is not special property of ownedBy is automatically nested in filter.
. ownedBy ( @type = AbstractRoleType and @path = inducement)
Organization Filters
Organization filters are used to filter objects based on their organization membership.
These filters operate on object as a whole, so item path must be .
(the dot).
Name | Value | Description |
---|---|---|
inOrg |
OID (UUID) |
Matches if object is part of organization unit or its subunits. |
isRoot |
N/A |
Matches if object is organization root. Filter does not have value. |
. inOrg "f9444d2d-b625-4d5c-befd-36c9b5861ac4"
-
All object which are members of specified organization and all its subunits (whole SUBTREE)
. inOrg[ONE_LEVEL] "f9444d2d-b625-4d5c-befd-36c9b5861ac4"
-
If you need to match only users in specified organization, use ONE_LEVEL matching rule.
. isRoot
-
All roles and organization units which are organization tree roots.
Other filters
Name | Value | Description |
---|---|---|
exists |
N/A |
Matches if item exists (has any value). Filter does not have value. |
type |
object type |
Matches if object is of specified type. Usually used in combination with |
Similarity filters
Filters are currently supported in midPoint native repository only |
To perform fuzzy (not exact) matching, midPoint query language provides 2 filters: levenshtein
and similarity
.
Aside from other filters, right side of the query consists of triplet of parameters enclosed in brackets. Their meaning is explained in following table:
Name | Value | Description | Parameters |
---|---|---|---|
levenshtein |
(value, threshold, inclusive) |
Matches objects where queried attribute has levenshtein distance lower than (or equal - depends on inclusive parameter value) the threshold specified. |
|
similarity |
(value, threshold, inclusive) |
Matches objects where queried attribute has similarity greater than (or equal - depends on inclusive parameter value) the threshold specified. |
|
As the filters are implemented using levenshtein PostgreSQL function and similarity PostgreSQL function, they work with native repository only.
name levenshtein ("ang",2,true)
-
All users whose name attribute has levenshtein distance 2 or lower from string "ang".
name levenshtein ("ang",2,false)
-
All users whose name has levenshtein distance lower than 2 from string "ang".
name similarity ('gren', 0.5, true)
-
All users whose name has similarity of 0.5 and lower to 'gren'.
The Levenshtein distance between two strings is the number of modifications required to transform one string (s1) into the other string (s2). It allows for single-character edits such as deletion, insertion, and substitution. For example, for s1=“helloIndia” and s2=“halloindia,” the Levenshtein distance is 2. |
Filtering all objects of specified type
Sometimes, in configuration files, you need to select all objects of specific object type. Object collection selecting all users in midPoint is an example of such case.
To select all objects just omit <filter>
element in the query or whole query.
The object collection below lists all roles (all objects of RoleType) in midPoint.
<objectCollection oid="72b1f98e-f587-4b9f-b92b-72e251dbb255">
<name>All roles</name>
<type>RoleType</type>
</objectCollection>
Query Examples
This chapter provides information and examples of queries in midPoint Query Language, mainly used in objects while configuration of midPoint itself.
Additional examples can be found in Advanced search - EXAMPLES.
Searching by Archetype Name
Search for reports with archetype specified by its name
archetypeRef/@/name = "Report export task"
Where :
-
archetypeRef/@
- specifies that we are not matching reference value, but it’s target. In this case it is archetype.
Search by Assigned Role Name
assignment/targetRef/@/name = "Role Name"
Where:
-
assignment/targetRef/@
-specifies that we are not matching reference value, but it’s target. In this case it is assigned role.
Users with account on specific resource
Search for users, which have account specified resource, with default intent.
linkRef/@ matches ( . type ShadowType and resourceRef matches (oid = "ff735c0a-21e3-11e8-a91a-df0065248d2d") and intent = "default" )
Where:
-
linkRef/@
- we dereference target oflinkRef
, this behaves similar to SQLJOIN
, allows us to filter on properties of the target -
matches
specifies subfilter for dereferenced target, filter which linkRef must match-
. type ShadowType
, we are searching for shadows on resource, this is necessary in order to be able to use shadow properties for filter -
resourceRef matches (oid = "…" )
- matches specific resource, to which shadow belongs -
intent = "default"
- matches shadow with default intent
-
All roles which are assigned to System users
UserType
as referencedBy. referencedBy ( @type = UserType and @path = assignment/targetRef and archetypeRef/@/name = "System user" )
AssignmentType
for referencedBy. referencedBy ( @type = AssignmentType and @path = targetRef and . ownedBy ( @type = UserType and @path = assignment and archetypeRef/@/name = "System user" ) )
All roles, which are assigned using inducement
Filter is currently supported in midPoint native repository only |
. referencedBy ( @type = AbstractRoleType and @path = inducement/targetRef )
All roles, which are assigned to administrator using full text serach
. referencedBy ( @type = UserType and @path = roleMembershipRef and . fullText "administrator" )
Search on assigned role using fullText
assignment/targetRef/@ matches ( . fullText "secret" )