title | description | author | ms.author | ms.reviewer | ms.topic | ms.localizationpriority | ms.subservice | ms.custom | ms.date |
---|---|---|---|---|---|---|---|---|---|
Advanced query capabilities on Microsoft Entra ID objects |
Microsoft Entra ID objects support advanced query capabilities to efficiently access data. |
FaithOmbongi |
ombongifaith |
Luca.Spolidoro |
concept-article |
high |
entra-applications |
graphiamtop20, scenarios:getting-started |
09/28/2023 |
As Microsoft Entra continues to deliver more capabilities and improvements in stability, availability, and performance, Microsoft Graph also continues to evolve and scale to efficiently access the data. One way is through Microsoft Graph's increasing support for advanced query capabilities on various Microsoft Entra ID objects, also called directory objects, and their properties. For example, the addition of not (not
), not equals (ne
), and ends with (endsWith
) operators on the $filter
query parameter.
The Microsoft Graph query engine uses an index store to fulfill query requests. To add support for additional query capabilities on some properties, these properties are now indexed in a separate store. This separate indexing allows Microsoft Entra ID to increase support and improve the performance of the query requests. However, these advanced query capabilities aren't available by default but, the requestor must also set the ConsistencyLevel header to eventual
and, except for $search
, use the $count
query parameter. The ConsistencyLevel header and $count
are referred to as advanced query parameters.
For example, to retrieve only inactive user accounts, you can run either of these queries that use the $filter
query parameter.
Option 1: Use the $filter
query parameter with the eq
operator. This request works by default, that is, the request doesn't require the advanced query parameters.
GET https://graph.microsoft.com/v1.0/users?$filter=accountEnabled eq false
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
Option 2: Use the $filter
query parameter with the ne
operator. This request isn't supported by default because the ne
operator is only supported in advanced queries. Therefore, you must add the ConsistencyLevel header set to eventual
and use the $count=true
query string.
GET https://graph.microsoft.com/v1.0/users?$filter=accountEnabled ne true&$count=true
ConsistencyLevel: eventual
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
These advanced query capabilities are supported only on directory objects and their relationships, including the following frequently used objects:
The following table lists query scenarios on directory objects that are supported only in advanced queries:
Description | Example |
---|---|
Use of $count as a URL segment |
GET ~/groups/$count |
Use of $count as a query string parameter |
GET ~/servicePrincipals?$count=true |
Use of $count in a $filter expression |
GET ~/users?$filter=assignedLicenses/$count eq 0&$count=true |
Use of $search |
GET ~/applications?$search="displayName:Browser" |
Use of $orderby on select properties |
GET ~/applications?$orderby=displayName&$count=true |
Use of $filter with the endsWith operator |
GET ~/users?$count=true&$filter=endsWith(mail,'@outlook.com') |
Use of $filter and $orderby in the same query |
GET ../applications?$orderby=displayName&$filter=startsWith(displayName, 'Box')&$count=true |
Use of $filter with the startsWith operators on specific properties. |
GET ~/users?$filter=startsWith(mobilePhone, '25478') OR startsWith(mobilePhone, '25473')&$count=true |
Use of $filter with ne and not operators |
GET ~/users?$filter=companyName ne null and NOT(companyName eq 'Microsoft')&$count=true |
Use of $filter with not and startsWith operators |
GET ~/users?$filter=NOT startsWith(displayName, 'Conf')&$count=true |
Use of $filter on a collection with endsWith operator |
GET ~/users?$count=true&$filter=proxyAddresses/any (p:endsWith(p, 'contoso.com'))&$select=id,displayName,proxyaddresses |
Use of OData cast with transitive members list | GET ~/me/transitiveMemberOf/microsoft.graph.group?$count=true |
Note
- Using
$filter
and$orderby
together is supported only with advanced queries. $expand
is not currently supported with advanced queries.- The advanced query capabilities are currently not available for Azure AD B2C tenants.
- To use advanced query capabilities in batch requests, specify the ConsistencyLevel header in the JSON body of the
POST
request.
Properties of directory objects behave differently in their support for query parameters. The following are common scenarios for directory objects:
- Queries that are supported by default will also work with advanced query parameters, but the response will be eventually consistent.
- The
in
operator is supported by default whenevereq
operator is supported by default. - The
endsWith
operator is supported only with advanced query parameters by mail, otherMails, userPrincipalName, and proxyAddresses properties. - Getting empty collections (
/$count eq 0
,/$count ne 0
) and collections with less than one object (/$count eq 1
,/$count ne 1
) is supported only with advanced query parameters. - The
not
andne
negation operators are supported only with advanced query parameters.- All properties that support the
eq
operator also supports thene
ornot
operators. - For queries that use the
any
lambda operator, use thenot
operator. See Filter using lambda operators.
- All properties that support the
The following tables summarize support for $filter
operators by properties of directory objects, and indicates where querying is supported through advanced query capabilities.
- The
$filter
operator works by default for that property. - The
$filter
operator requires advanced query parameters, which are:ConsistencyLevel=eventual
header$count=true
query string
- The
$filter
operator isn't supported on that property. Send us feedback to request that this property support$filter
for your scenarios. - Blank cells indicate that the query isn't valid for that property.
- The null value column indicates that the property is nullable and filterable using
null
. - Properties that aren't listed here don't support
$filter
at all.
[!INCLUDE filter-directory-objects]
The following table summarizes support for $orderby
by properties of directory objects and indicates where sorting is supported through advanced query capabilities.
- The
$orderby
operator works by default for that property. - The
$orderby
operator requires advanced query parameters, which are:ConsistencyLevel=eventual
header$count=true
query string
- Use of
$filter
and$orderby
in the same query for directory objects always requires advanced query parameters. For more information, see Query scenarios that require advanced query capabilities.
Counting directory objects is only supported using the advanced queries parameters. If the ConsistencyLevel=eventual
header isn't specified, the request returns an error when the $count
URL segment is used or silently ignores the $count
query parameter (?$count=true
) if it's used.
GET https://graph.microsoft.com/v1.0/users/$count
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
{
"error": {
"code": "Request_BadRequest",
"message": "$count is not currently supported.",
"innerError": {
"date": "2021-05-18T19:03:10",
"request-id": "d9bbd4d8-bb2d-44e6-99a1-71a9516da744",
"client-request-id": "539da3bd-942f-25db-636b-27f6f6e8eae4"
}
}
}
For directory objects, $search
works only in advanced queries. If the ConsistencyLevel header isn't specified, the request returns an error.
GET https://graph.microsoft.com/v1.0/applications?$search="displayName:Browser"
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "Request with $search query parameter only works through MSGraph with a special request header: 'ConsistencyLevel: eventual'",
"innerError": {
"date": "2021-05-27T14:26:47",
"request-id": "9b600954-ba11-4899-8ce9-6abad341f299",
"client-request-id": "7964ef27-13a3-6ca4-ed7b-73c271110867"
}
}
}
If a property or query parameter in the URL is supported only in advanced queries but either the ConsistencyLevel header or the $count=true
query string is missing, the request returns an error.
GET https://graph.microsoft.com/beta/users?$filter=endsWith(userPrincipalName,'%23EXT%23@contoso.com')
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE snippet-not-available] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "Operator 'endsWith' is not supported because the required parameters might be missing. Try adding $count=true query parameter and ConsistencyLevel:eventual header. Refer to https://aka.ms/graph-docs/advanced-queries for more information",
"innerError": {
"date": "2023-07-14T08:43:39",
"request-id": "b3731da7-5c46-4c37-a8e5-b190124d2531",
"client-request-id": "a1556ddf-4794-929d-0105-b753a78b4c68"
}
}
}
If a property hasn't been indexed to support a query parameter, even if the advanced query parameters are specified, the request returns an error.
GET https://graph.microsoft.com/beta/groups?$filter=createdDateTime ge 2021-11-01&$count=true
ConsistencyLevel: eventual
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "Unsupported or invalid query filter clause specified for property 'createdDateTime' of resource 'Group'.",
"innerError": {
"date": "2023-07-14T08:42:44",
"request-id": "b6a5f998-94c8-430d-846d-2eaae3031492",
"client-request-id": "2be83e05-649e-2508-bcd9-62e666168fc8"
}
}
}
However, a request that includes query parameters might fail silently. For example, for unsupported query parameters and for unsupported combinations of query parameters. In these cases, examine the data returned by the request to determine whether the query parameters you specified had the desired effect. For example, in the following example, the @odata.count
parameter is missing even if the query is successful.
GET https://graph.microsoft.com/v1.0/users?$count=true
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
[!INCLUDE sample-code] [!INCLUDE sdk-documentation]
HTTP/1.1 200 OK
Content-type: application/json
{
"@odata.context":"https://graph.microsoft.com/v1.0/$metadata#users",
"value":[
{
"displayName":"Oscar Ward",
"mail":"oscarward@contoso.com",
"userPrincipalName":"oscarward@contoso.com"
}
]
}