midPoint Query Language Filters

Last modified 30 Jun 2025 15:12 +02:00

This page describes how filters are constructed using midPoint Query Language (MQL).

Overview

For filtering in midPoint, the following components are required:

Optionally, you can also include paging (for result size and offset), and sorting (for ordering results).

In GUI, object type is defined by the context, i.e. the current page, while paging and sorting are controlled in the results table.

Filter Structure

Simple filters usually take the form of triplets consisting of:

  • Item path: Specifies the searchable item to which the filter is applied.

  • Filter name: Defines the name of the filter.

  • Value: Defines a value literal or item path that should be matched according to the filter specification.

Advanced filters may follow a similar structure but can also be more sophisticated. See individual Advanced filters.

Item Path

Item path specifies the item by which data are filtered. In its simplest form, it is a name of an object property, or names of items and containers separated by slashes, such as:

  • fullName

  • activation/administrativeStatus

  • attributes/uid

For details, refer to Item path.

Filter Name

The filter name, or its alias, specifies a filtering condition that should be used.

Value

Values are usually string literals enclosed in double quotes. However, values can take various forms. For example, a value may be a path to another item, e.g. when the query compares two items.

In some cases, values may be complex. The exact form of the value part of the filter depends on the operator and the 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 require quotes. Valid values are true and false.

string

emailAddress endsWith "testorg.com"

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

PolystringType

givenName = 'Adam'

Values of the polystring type are enclosed in quotes (') or double quotes (").

int

extension/height > 170

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

float

extension/perfScore > 1.05

Number values do not require 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 ("). They can be compared as dates, or as date and time (following the ISO-8601 format).

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

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

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

As datetime values contain the exact time value (down to milliseconds), you need to compare dates as intervals.

QName

assignment/targetRef matches (relation=owner)

QName values (a relation in this example) are entered into queries without quotation marks.

assignment/targetRef matches (relation=org:owner)

QNames may use namespaces. Unless values conflict, namespaces are not necessary in queries. In this case, both relation=owner and relation=org:owner return the same results.

Object Type Definition

Midpoint performs queries over a defined set of objects. While in GUI, this set is defined by the currently opened view, in configuration, you need to specify the object type for a query explicitly. This is done outside of the filter query. See the configuration snippet below in which the query selects User with the 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>

Simple Filters

Comparison Filters

Comparison filters are used to compare attribute or property values against specified criteria. These filters operate on simple data types like strings, numbers, or dates, and are commonly used to match objects where a property equals a certain value, contains, or falls within a range.

While the path is commonly referenced on the left, and a value or pattern on the right side, comparison filters also support item paths on the right side. For example, activation/validFrom > activation/validTo should return all objects with incorrectly set activations, i.e. objects for which the activation starts after it ends.

The following table summarizes common comparison filters:

Name Alias Description

equal

=

Matches items equal to a value.

notEqual

!=

Matches items different from a value.

less

<

Matches items smaller than a value.

lessOrEqual

<=

Matches items smaller or equal to a value.

greater

>

Matches items greater than a value.

greaterOrEqual

>=

Matches items greater or equal to a value.

Examples of using comparison filters on users:
familyName = "Doe"

Equals filter, searches for all users with the familyName of "Doe".

familyName = ("Doe", "Smith")

Equals multi-value filter, searches for all users with the familyName of "Doe" or "Smith".

name != "Administrator"

Not equals filter, searches for everyone except for "Administrator".

name != ("Administrator", "Leonardo")

Not equals multi-value filter, searches for everyone except for "Administrator" and "Leonardo".

activation/validTo < "2022-01-01"

Less filter, searches for all users that will not be valid after 2021.

In Equal (=) and notEqual (!=) filters, you can enclose multiple values within brackets on the right side of the query. The query name = ("adam","john") provides the same results as name = "adam" or name = "john" .

Matching Rules

Matching rules filters are a specialized subset of comparison filters designed to perform more flexible, rule-based comparisons of attribute values. They are useful when strict equality is too limiting and when a domain-specific matching logic is required. They are typically used when you want to be more tolerant, for example to disregard varying casing in usernames, or to tolerate the use of whitespaces in various values.

The syntax of a matching rule in a query is: filter[matchingRuleName]

For a list of all matching rules, refer to the Matching Rules page.

Example usage
givenName =[origIgnoreCase] "Adam"

Query matches all cases of "Adam" in givenName with various casings, such as 'Adam', 'adam', or 'ADAM'.

emailAddress endsWith[stringIgnoreCase] "@test.com"

Query matches users with email addresses that end with the "test.com" domain.

String Filters

String filters are used to query objects based on textual properties, such as names, identifiers, or email addresses. String values must be enclosed in single (') or double (") quotation marks, and queries are case-sensitive.

These filters are useful when searching for users, roles, or organizational units based on partial or complete string values.

In addition to common filters, such as equal or notEqual, the following filters can be applied to string and polystring values:

Name Description

startsWith

Matches items starting with a specified string.

contains

Matches string properties that contain a specified substring.

endsWith

Matches string properties that end in a specified substring.

fullText

Performs a full text search. The item path must be a dot (.)

Logical Filters

Logical filters combine several subfilters into one filter using logical operators. They enable you to search for objects, such as users, that meet multiple criteria simultaneously, or to exclude certain matches.

In more complex filters, you can use brackets to group logical statements for better readability. If you do not use brackets, midPoint will evaluate the filter following this logic:

  • not is evaluated first as it changes the meaning of the filter.

  • and is evaluated next.

  • or is evaluated last.

The following logical operators are available:

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 has to be true.

not

givenName not startsWith "J"
givenName != "John"
not ( givenName = "Leonardo" )

Logical negation where not prefixes the filter name.

See the following examples of filters:

givenName = "John" and familyName = "Doe"
familyName = "Doe" and (givenName = "John" or givenName ="Bill")

Advanced Filters

Advanced filters are typically used in assignment conditions, object templates, policy rules, and archetype definitions. Their structure reflects the internal schema of the queried objects.

A key aspect of advanced filters is that they operate in the context of a specific object. They support path-based navigation and so enable you to target deeply nested attributes.

Filters can compare values, evaluate object relationships, or perform self-referencing using “.” which refers to the currently evaluated midPoint object.

The following advanced filters are available:

Matches Filter

The matches filter operates on a container or a structured value, and specifies conditions that must be met by a single container value.

It is in the form of itemPath matches (subfilter), where subfilter (and item paths) are relative to the container, for example assignment/validTo < "2022-01-01" is the same as assignment matches (validTo < "2022-01-01").

The subfilter is any of the supported filters in which paths are relative to the container. It enables you to specify multiple conditions (joined using Logical Filters) that must be met by container values.

An example of the matches filter:

activation matches (
  validFrom > "2022-01-01"
   and validTo <"2023-01-01"
)

For filters that match multiple properties of multi-value containers (such as assignment), it is important to consider if you want to match a container where one container value meets all criteria, or if these criteria could be met by multiple different container values.

If these multiple criteria are to be met by a single container value, you must use the Matches filter.

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"). The first filter will match users who have one assignment starting after 2022, and potentially, another assignment ending by 2023. The second filter with match users who have an assignment which starts in 2022 and expires before 2023.

inOid Filter

Unlike path-based filters, inOid filters are used to match objects whose object identifiers (OID) are included directly in a specified list. This is used when you already have a list of known object identifiers and want to retrieve or process the corresponding objects.

An inOid query is a triplet consisting of an object representation, an inOid filter, and a list of OID values enclosed in brackets.

An example of querying one specific object by its OID:

. inOid ("00000000-0000-0000-0000-000000000702")

An example of querying 2 specific objects by their OIDs:

. inOid ("eb21455d-17cc-4390-a736-f1d6afa82057", "87e048ae-6fcf-47bb-a55e-60acb8604ead")

Reference Filters

Reference filters are used to find objects that have a reference (like targetRef or orgRef) pointing to another object. You can then filter these based on the properties of the referenced object. To do that, you use the @ operator, which lets you access properties of the referenced object, not just the reference itself.

These filters are typically used to query or restrict relationships between objects, such as finding all objects assigned to a particular role, or all tasks owned by a specific user.

You can also perform inverse queries using the referencedBy filter to search for an object by properties of its referencer. For example, you can search for roles by properties of their members.

Matches Filter in References

Matches filters can be used to query reference-type properties, such as targetRef, based on specific properties of the reference. While you can filter by OID alone in midPoint, matches filters enable you to filter references by additional metadata.

You can filter by the following properties:

  • oid matches the target OID exactly (UUID as a string). Example: assignment/targetRef matches (oid = efaf89f4-77e9-460b-abc2-0fbfd60d9167)

  • relation matches any reference with a specified relation (QName). Example: roleMembershipRef matches (relation = manager)

  • targetType matches any reference with a specified target type (QName). Example: roleMembershipRef matches (targetType = OrgType)

You can use any combination of these three properties of a reference, however, only equals and and filters are supported. This limits the maximum number of conditions that you can use in a filter to three (see the example below). However, you can workaround this limitation, and enhance matches filters, using dereferencing which enables you to match the three properties on multiple objects.

roleMembershipRef matches (
  oid = "bc3f7659-e8d8-4f56-a647-2a352eead720"
  and relation = manager
  and targetType = OrgType
)

Dereferencing

With dereferencing, you can write filter conditions which are executed on referenced objects. Dereferencing is done using the @ special character in the item path after the reference. For example, the assignment/targetRef/@ item path points to an object referenced by targetRef instead of targetRef itself. This enables you to enhance paths with properties of referenced objects, such as assignment/targetRef/@/name which means the name of the assigned object.

For example, dereferencing enables you to search for users with a specific assigned role by the role name instead of its OID, even if the execution time will be slightly longer since we need to dereference objects. assignment/targetRef/@/name = "Superuser" matches any user who is directly assigned the superuser role.

  • To also match users who are assigned a role indirectly, you should use roleMembershipRef instead of assignment/targetRef.

  • If you need to match a referenced object on multiple properties, you should use the Matches filter.

  • Dereferencing is not supported in authorizations, in-memory, and in resource searches. It is also not supported for object references defined via schema extensions.

Dereferencing Inside Reference Matches Filter

You can use dereferencing inside a Reference Matches filter to match properties of a reference, and also properties of its target, i.e. not just the reference itself. This means you can write a query that looks at attributes of the referenced object, such as the role name or user’s organization, rather than matching only the OID or the type of the reference.

This is done using a reference filter combined with subfilters which apply to the dereferenced target object. For example, you can find users assigned to roles with a specific name, without needing to know the role’s OID.

Find all users who are managers for roles with the 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 The type of the referenced target should be RoleType.
3 The relation of users to the assigned role is manager.
4 We dereference the target and match its properties.
5 Name of the role archetype should be Business Role. This is done by dereferencing archetypeRef, using @ in the item path.

This feature is currently supported only in the midPoint native repository. It is not supported in authorizations, in-memory and in resource searches.

referencedBy Filter

The referencedBy filter is a reverse-search filter.

It scans through objects of a specified type (such as Roles or Accounts), looks in a specified reference path (such as assignment/targetRef), and returns those objects where the reference points to the object being evaluated, and that match the given filter.

You can use this filter, for example, to find users that are not referenced by any provisioning targets, i.e. clean up unused objects, or to find incoming references, for example to find all roles that include a user in an assignment.

In order to use a referencedBy filter, you must also specify:

  • The type of objects which it references.

  • The path of the object reference which is used for the reference (e.g. assignment/targetRef or inducement/targetRef).

This looks for all roles assigned to Administrator:
. referencedBy ( (1)
  @type = UserType (2)
  and @path = assignment/targetRef (3)
  and name = "Administrator" (4)
)
1 referencedBy is the filter name.
2 @type (required) is a special filter property which specifies the type of objects that should be considered when evaluating the filter. In this case, we are interested in users.
3 @path (required) is a special filter property which specifies which object reference should be used in the filter. In this case, we are interested in directly assigned roles (assignment/targetRef).
4 The filter which the referencing object must match. In this case, the name of the referencing object must be Administrator.
referencedBy filters are not supported for object references defined via schema extensions.

ownedBy Filter

With ownedBy filters, you can find objects that are embedded inside a parent container object, such as assignments, or inducements. This is useful when querying container values that do not exist independently but are part of a larger object.

The syntax of this filter is similar to that of the referencedBy filter.

You can only apply ownedBy filters to the current object path (.).

The properties of ownedBy filter are:

  • type: (Required) Defines the type of the parent/owner.

  • path: Defines the name/location of the container inside the parent.

  • filter: Specifies a filter to which the parent needs to conform. The filter is an explicit element in XML/YAML/JSON. In midPoint queries, any filter that is not a special property of ownedBy is automatically treated as a nested filter.

The following example looks for all inducements:
. ownedBy ( @type = AbstractRoleType and @path = inducement)

ownedBy filters are currently only supported in the midPoint native repository. They are not supported in authorizations, in-memory, and in resource searches.

Organization Filters

Organization filters are used to filter objects based on their organization membership.

These filters can help you, for example, assign roles to users under a certain department or location, or restrict access to users belonging to a specific organizational branch.

Organization filters specify the object identifier (OID) of an organization unit, and can include a scope to control whether only direct members or all descendants in the hierarchy are matched. This makes them ideal for queries like "find all users under department X", or "get all roles withing this branch of the organization tree".

These filters operate on an object as a whole and so the item path must be . (the dot).

Name Value Description

inOrg

OID (UUID)

Matches an object if it is a part of an organization unit or its subunits.
By default, the filter searches in the entire organization unit subtree.
To limit the search only to direct children of the specified organization unit, and to exclude deeper nested units, use the [ONE_LEVEL] option.

isRoot

N/A

Matches an object if it is the organization root. This filter does not have any values.

. inOrg "f9444d2d-b625-4d5c-befd-36c9b5861ac4"

Matches all objects that are members of the specified organization and all its subunits (whole SUBTREE).

. inOrg[ONE_LEVEL] "f9444d2d-b625-4d5c-befd-36c9b5861ac4"

If you only need to match users in a specified organization, use the ONE_LEVEL matching rule.

. isRoot

Matches all roles and organization units that are organization tree roots.

Similarity Filters

Similarity filters are used to perform fuzzy, i.e. not exact, matches. This makes them suitable for correlation, where you need to find the best match even if there is no exact identifier (such as an employee ID). With similarity filters, you have the flexibility to use fuzzy matching based on name, email, etc. instead. However, you can also use similarity filters in manual searches to find similar results to what you were looking for, when the original search did not return any results.

MQL provides the following fuzzy filters:

  • levenshtein

  • similarity

Contrary to other filters, the right side of the query consists of a triplet of parameters enclosed in brackets. Their meaning is explained in following table:

Name Value Description Parameters

levenshtein

(value, threshold, inclusive)

Matches objects for which the queried attribute has the Levenshtein distance lower than (or equal to, depending on the inclusive parameter value) the specified threshold.

  • Value (string): A string value that is compared with the queried attribute.

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

  • Inclusive (boolean): Defines if objects with the threshold value should be included in the result (true) or not (false).

similarity

(value, threshold, inclusive)

Matches objects for which the queried attribute has similarity greater than (or equal to, depending on the inclusive parameter value) the specified threshold.
Similarity of 1 means an exact match, while 0 means no similarity.

  • Value (string): A string value that is compared with the queried attribute.

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

  • Inclusive (boolean): Defines if objects with the threshold value should be included in the result (true) or not (false).

As similarity filters are implemented using levenshtein PostgreSQL function and similarity PostgreSQL function, they only work with the native repository.

name levenshtein ("ang",2,true)

Matches all users whose name attribute has Levenshtein distance 2 or lower from the string "ang".

name levenshtein ("ang",2,false)

Matches all users whose name has Levenshtein distance lower than 2 from the string "ang".

name similarity ('gren', 0.5, true)

Matches all users whose name has similarity of 0.5 or lower from the string '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.

Other Filters

MidPoint provides also additional unsorted filters that extend the functionality of the other available filters. They are typically used to refine queries by existence checks or to constrain results to objects of a particular class.

Name Value Description

exists

N/A

Matches an item if it exists, i.e. if it has a value. This filter does not have a value.

type

object type

Matches an object if it is of the specified type. This is usually used in combination with the and filter for dereferenced objects, or when you need to match a property defined in a more specific type.

Was this page helpful?
YES NO
Thanks for your feedback