Introduction to midPoint Query Language

Last modified 13 Sep 2024 14:35 +02:00

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

equal

=

Matches if any item is equal to value

not equal

notEqual

!=

Matches if item is different from value

less

<

Matches if item is smaller than value

lessOrEqual

<=

Matches if item is smaller or equal to the value

greater

>

Matches if item is greater than value

greaterOrEqual

>=

Matches if item is greater or equal to value

Examples of comparison filters on users
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]

Example of matching rules usage
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

startsWith

Matches if item starts with specified string.

contains

Matches string property if it contains specified substring.

endsWith

Matches string property if it ends with specified substring.

fullText

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

extension/coreMember = true

Boolean values do not need quotes. Allowed values are true and false.

string

emailAddress endsWith "testorg.com"

String values are enclosed in quotes (') or double quotes (").

PolystringType

givenName = 'Adam'

Values of PolystringType are enclosed in quotes (') or double quotes (").

int

extension/height > 170

Number values do not need quotes. Only common property filters (=,>, ..) are defined for number types.

float

extension/perfScore > 1.05

Number values do not need quotes. Only common property filters (=,>, ..) are defined for number types.

dateTime

metadata/createTimestamp >= "2024-03-01"

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.

metadata/createTimestamp >= "2024-03-01T15:30:00"

While comparing time values. DateTime values entered without timezone are considered to be in the same timezone as running midPoint.

extension/empStartDate >= "2019-10-01" and extension/empStartDate < "2019-10-02"

As datetime values contain exact time value up to milliseconds you need to compare dates as intervals. See examples.

ObjectReferenceType

assignment/targetRef/@/name = "End user"

Object references are queried using matches filter or dereferencing operator @. See Advanced filters chapter below.

QName

assignment/targetRef matches (relation=owner)

QName values (relation in this example) are entered into query without quotation marks. Do not use them.

assignment/targetRef matches (relation=org:owner)

QNames may use namespaces. The namespaces are not necessary in the query - of course, if the values don’t collide. So, both queries with relation=owner or relation=org:owner returns the same results.

Logical Filters

Logical filters are used to combine several sub-filters into one filter or to negate filter.

givenName = "John" and familyName = "Doe"

There is a usual set of logic operators:

Table 1. Logical Operators
Operator Example Description

and

givenName = "John" and familyName = "Doe"

All subfilters must be true.

or

givenName = "Bill" or nickName = "Bill"

Any of the subfilters is true.

not

givenName not startsWith "J"
givenName != "John"

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 assignment). It is important to consider if we want to match a container where one container value meets all criteria, or these criteria could be met by multiple different container values.

If these multiple criteria must be met by one container value you must use matches.

The filter assignment/validFrom > "2022-01-01" and assignment/validTo <"2023-01-01" is different from assignment matches (validFrom > "2022-01-01" and validTo <"2023-01-01"). First will match user who has one assignment starting after 2022 and possible other assignment ending by 2023. The second filter with match user who has an assignment which starts in 2022 and expires before 2023.

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 (…​).

Find all users, which are managers for roles with Business Role archetype
assignment/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:

Find all roles which are assigned to Administrator
. 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.

Using searchContainers, find all inducements
. 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 and filter for dereferenced objects, or it is needed to match on property defined in more specific type.

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.

  • value (string) - string value that is compared with queried attribute.

  • threshold (integer) - the compared distance value. The result must be less than (or equal) the threshold.

  • inclusive (boolean) - whether objects with threshold value would be included in result (true) or not (false).

similarity

(value, threshold, inclusive)

Matches objects where queried attribute has similarity greater than (or equal - depends on inclusive parameter value) the threshold specified.
Similarity of 1 mean exact match, 0 no similarity.

  • value (string) - string value that is compared with queried attribute.

  • threshold (float) - the compared distance value. The result must be greater than (or equal) the threshold.

  • inclusive (boolean) - whether objects with threshold value would be included in result (true) or not (false).

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

midPoint Query
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

midPoint Query
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.

midPoint Query
linkRef/@ matches (
  . type ShadowType
  and resourceRef matches (oid = "ff735c0a-21e3-11e8-a91a-df0065248d2d")
  and intent = "default"
)

Where:

  • linkRef/@ - we dereference target of linkRef, this behaves similar to SQL JOIN, 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

midPoint Query using UserType as referencedBy
. referencedBy (
  @type = UserType
  and @path = assignment/targetRef
  and archetypeRef/@/name = "System user"
)
midPoint Query using 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
midPoint Query
. referencedBy (
  @type = AbstractRoleType
  and @path = inducement/targetRef
)

All roles, which are assigned to administrator using full text serach

midPoint Query
. referencedBy (
   @type = UserType
   and @path = roleMembershipRef
   and . fullText "administrator"
)

Search on assigned role using fullText

midPoint Query
assignment/targetRef/@ matches (
   . fullText "secret"
)
Was this page helpful?
YES NO
Thanks for your feedback