Azure AD 对象上的高级查询功能
随着 Azure Active Directory (Azure AD) 继续在稳定性、可用性和性能方面提供更多功能和改进,Microsoft Graph 也会不断改进和缩放,以有效地访问数据。 一种方法是通过 Microsoft Graph 对各种 Azure AD 对象(也称为目录对象及其属性)的高级查询功能的支持不断增加。 例如,在 $filter
查询参数上添加 not (not
),不等于 (ne
),以 (endsWith
) 运算符结尾。
Microsoft Graph 查询引擎使用索引存储来满足查询请求。 为了添加对某些属性的其他查询功能的支持,这些属性现在在单独的存储中编制索引。 这种单独的索引使 Azure AD 可以增加支持并提高查询请求的性能。 但是,默认情况下,这些高级查询功能不可用,但请求者还必须将 ConsistencyLevel 标头设置为 eventual
,并且(除了 $search
)使用 $count
查询参数。 ConsistencyLevel标头和$count
被称为高级查询参数。
例如,要仅检索非活动用户帐户,你可以运行使用 $filter
查询参数的查询之一。
选项 1:将
$filter
查询参数与 运算符eq
一同使用。 默认情况下,此请求将起作用,即请求不需要高级查询参数。GET https://graph.microsoft.com/v1.0/users?$filter=accountEnabled eq false
选项 2:将
$filter
查询参数与 运算符ne
一同使用。 默认情况下不支持此请求,因为仅在高级查询中支持ne
运算符。 因此,必须将 ConsistencyLevel 标头设置为eventual
,并使用$count=true
查询字符串。GET https://graph.microsoft.com/v1.0/users?$filter=accountEnabled ne true&$count=true ConsistencyLevel: eventual
仅目录对象及其关系支持这些高级查询功能,包括以下常用对象:
下表列出了仅在高级查询中支持的目录对象的查询方案:
说明 | 示例 |
---|---|
使用 $count 作为 URL 段 |
GET~/groups/$count |
使用 $count 作为查询字符串参数 |
GET~/servicePrincipals?$count=true |
在 $filter 表达式中使用 $count |
GET~/users?$filter=assignedLicenses/$count eq 0&$count=true |
使用 $search |
GET~/applications?$search="displayName:Browser" |
对选择属性使用 $orderby |
GET~/applications?$orderby=displayName&$count=true |
将 $filter 与 endsWith 运算符结合使用 |
GET~/users?$count=true&$filter=endsWith(mail,'@outlook.com') |
在同一查询中使用$filter 和$orderby |
GET../applications?$orderby=displayName&$filter=startsWith( displayName, 'Box')&$count=true |
对特定属性将 $filter 与 startsWith 运算符结合使用. |
GET~/users?$filter=startsWith(mobilePhone, '25478') OR startsWith(mobilePhone, '25473')&$count=true |
将 $filter 与 ne 和 not 运算符结合使用 |
GET~/users?$filter=companyName ne null and NOT(companyName eq 'Microsoft')&$count=true |
将 $filter 与 not 和 startsWith 运算符结合使用 |
GET~/users?$filter=NOT startsWith(displayName, 'Conf')&$count=true |
在带有 endsWith 运算符的集合上使用 $filter |
GET~/users?$count=true&$filter=proxyAddresses/any (p:endsWith(p, 'OnMicrosoft.com'))&$select=id,displayName,proxyaddresses |
将 OData 强制转换与可传递成员列表配合使用 | GET~/me/transitiveMemberOf/microsoft.graph.group?$count=true |
注意
- 仅高级查询支持将
$filter
和$orderBy
结合使用。 - 高级查询当前不支持
$expand
。 - 高级查询功能目前不适用于Azure AD B2C租户。
- 若要在 批处理请求 中使用高级查询功能,请在
POST
请求的 JSON 正文中指定 ConsistencyLevel 标头。
支持对 Azure AD (目录) 对象的属性进行筛选
目录对象的属性对查询参数的支持行为各不相同。 以下是目录对象的常见应用场景:
- 默认情况下支持的查询也适用于高级查询参数,但响应最终会一致。
- 默认情况下,只要默认支持
eq
运算符,则默认支持in
运算符。 endsWith
仅通过 mail、otherMails、userPrincipalName 和 proxyAddresses 属性的高级查询参数支持运算符。- 获取空集合 (
/$count eq 0
、/$count ne 0
) 和对象少于 (/$count eq 1
的集合,/$count ne 1
) 仅支持高级查询参数。 not
和ne
求反运算符仅支持高级查询参数。- 支持
eq
运算符的所有属性也支持ne
或not
运算符。 - 对于使用
any
lambda 运算符的查询,请使用not
运算符。 请参阅使用 lambda 运算符的筛选器。
- 支持
下表汇总了对高级 $filter
查询功能支持的目录对象属性的操作器的支持。
图例
运算符
$filter
默认适用于该属性。运算符
$filter
需要高级查询参数,这些参数包括:ConsistencyLevel=eventual
标头$count=true
查询字符串
该
$filter
属性不支持 运算符。 向我们发送反馈 ,请求此属性支持$filter
方案。- 空白单元格指示查询对该属性无效。
- 列 null 值 指示该属性可为 null 且可使用
null
筛选。 - 此处未列出的属性完全不支持
$filter
。
管理单元属性
属性 | eq | startsWith | eq Null |
---|---|---|---|
说明 | |||
displayName | |||
isMemberManagementRestricted | |||
scopedRoleMembers/any (s:s/id) |
应用程序属性
属性 | eq | startsWith | ge/le | eq Null | eq 计数 0 |
---|---|---|---|---|---|
appId | |||||
createdDateTime | |||||
createdOnBehalfOf/id | |||||
说明 | |||||
disabledByMicrosoftStatus | |||||
displayName | |||||
extensionProperties/$count | |||||
federatedIdentityCredentials/$count | |||||
federatedIdentityCredentials/any (f:f/issuer) | |||||
federatedIdentityCredentials/any (f:f/name) | |||||
federatedIdentityCredentials/any (f:f/subject) | |||||
identifierUris/any(p:p) | |||||
info/logoUrl | |||||
info/termsOfServiceUrl | |||||
owners/$count | |||||
publicClient/redirectUris/any(p:p) | |||||
publisherDomain | |||||
requiredResourceAccess/any(r:r/resourceAppId) | |||||
serviceManagementReference | |||||
signInAudience | |||||
spa/redirectUris/any(p:p) | |||||
tags/any(p:p) | |||||
唯一名称 | |||||
verifiedPublisher/displayName | |||||
web/homePageUrl | |||||
web/redirectUris/any(p:p) |
协定属性
属性 | eq | startsWith |
---|---|---|
customerId | ||
defaultDomainName | ||
displayName |
设备属性
FormattedProperty | eq | startsWith | ge/le | eq Null | eq 计数 0 |
---|---|---|---|---|---|
accountEnabled | |||||
alternativeSecurityIds/any(a:a/identityProvider) | |||||
alternativeSecurityIds/any(a:a/type) | |||||
approximateLastSignInDateTime | |||||
deviceId | |||||
displayName | |||||
extensionAttributes/extensionAttribute1 | |||||
extensionAttributes/extensionAttribute10 | |||||
extensionAttributes/extensionAttribute11 | |||||
extensionAttributes/extensionAttribute12 | |||||
extensionAttributes/extensionAttribute13 | |||||
extensionAttributes/extensionAttribute14 | |||||
extensionAttributes/extensionAttribute15 | |||||
extensionAttributes/extensionAttribute2 | |||||
extensionAttributes/extensionAttribute3 | |||||
extensionAttributes/extensionAttribute4 | |||||
extensionAttributes/extensionAttribute5 | |||||
extensionAttributes/extensionAttribute6 | |||||
extensionAttributes/extensionAttribute7 | |||||
extensionAttributes/extensionAttribute8 | |||||
extensionAttributes/extensionAttribute9 | |||||
hostnames/any(p:p) | |||||
isCompliant | |||||
isManaged | |||||
mdmAppId | |||||
onPremisesLastSyncDateTime | |||||
onPremisesSyncEnabled | |||||
operatingSystem | |||||
operatingSystemVersion | |||||
physicalIds/$count | |||||
physicalIds/any(p:p) | |||||
registrationDateTime | |||||
systemLabels/$count |
目录角色属性
属性 | eq | startsWith | eq Null |
---|---|---|---|
说明 | |||
displayName | |||
roleTemplateId |
组属性
属性 | eq | startsWith | ge/le | eq Null | eq 计数 0 |
---|---|---|---|---|---|
appRoleAssignments/any (a:a/id) | |||||
assignedLicenses/any(a:a/skuId) | |||||
classification | |||||
createdByAppId | |||||
createdOnBehalfOf/id | |||||
说明 | |||||
displayName | |||||
expirationDateTime | |||||
hasMembersWithLicenseErrors | |||||
infoCatalogs/any(p:p) | |||||
isAssignableToRole | |||||
mailEnabled | |||||
mailNickname | |||||
membershipRule | |||||
onPremisesLastSyncDateTime | |||||
onPremisesProvisioningErrors/$count | |||||
onPremisesProvisioningErrors/any(o:o/category) | |||||
onPremisesProvisioningErrors/any(o:o/propertyCausingError) | |||||
onPremisesSamAccountName | |||||
onPremisesSecurityIdentifier | |||||
onPremisesSyncEnabled | |||||
owners/$count | |||||
preferredLanguage | |||||
proxyAddresses/$count | |||||
proxyAddresses/any(p:p) | |||||
renewedDateTime | |||||
resourceBehaviorOptions/any(p:p) | |||||
resourceProvisioningOptions/any(p:p) | |||||
securityEnabled | |||||
settings/any (s:s/displayName) | |||||
settings/any (s:s/id) |
组织联系人属性
属性 | eq | startsWith | ge/le | eq Null | eq 计数 0 |
---|---|---|---|---|---|
CompanyName | |||||
department | |||||
displayName | |||||
givenName | |||||
jobTitle | |||||
mailNickname | |||||
manager/id | |||||
onPremisesLastSyncDateTime | |||||
onPremisesProvisioningErrors/$count | |||||
onPremisesProvisioningErrors/any(o:o/category) | |||||
onPremisesProvisioningErrors/any(o:o/propertyCausingError) | |||||
onPremisesSyncEnabled | |||||
proxyAddresses/$count | |||||
proxyAddresses/any(p:p) | |||||
surname |
服务主体属性
属性 | eq | startsWith | ge/le | eq Null | eq 计数 0 |
---|---|---|---|---|---|
accountEnabled | |||||
alternativeNames/any (p:p) | |||||
appId | |||||
appOwnerOrganizationId | |||||
appRoleAssignedTo/any (a:a/id) | |||||
appRoleAssignmentRequired | |||||
appRoleAssignments/any (a:a/id) | |||||
applicationTemplateId | |||||
createdObjects/any(c:c/id) | |||||
delegatedPermissionClassifications/any (d:d/id) | |||||
说明 | |||||
displayName | |||||
federatedIdentityCredentials/$count | |||||
federatedIdentityCredentials/any (f:f/issuer) | |||||
federatedIdentityCredentials/any (f:f/name) | |||||
federatedIdentityCredentials/any (f:f/subject) | |||||
homepage | |||||
info/logoUrl | |||||
info/termsOfServiceUrl | |||||
oauth2PermissionGrants/任何 (o:o/id) | |||||
ownedObjects/$count | |||||
owners/$count | |||||
preferredTokenSigningKeyEndDateTime | |||||
publisherName | |||||
servicePrincipalNames/any (p:p) | |||||
servicePrincipalType | |||||
tags/any(p:p) | |||||
verifiedPublisher/displayName |
用户属性
FormattedProperty | eq | startsWith | ge/le | eq Null | eq 计数 0 |
---|---|---|---|---|---|
accountEnabled | |||||
ageGroup | |||||
appRoleAssignments/any (a:a/id) | |||||
assignedLicenses/$count | |||||
assignedLicenses/any(a:a/skuId) | |||||
assignedPlans/any(a:a/capabilityStatus) | |||||
assignedPlans/any(a:a/service) | |||||
assignedPlans/any(a:a/servicePlanId) | |||||
authorizationInfo/certificateUserIds/any (p:p) | |||||
businessPhones/any (p:p) | |||||
城市 | |||||
CompanyName | |||||
consentProvidedForMinor | |||||
country | |||||
createdDateTime | |||||
createdObjects/any(c:c/id) | |||||
creationType | |||||
department | |||||
displayName | |||||
employeeHireDate | |||||
employeeId | |||||
employeeOrgData/costCenter | |||||
employeeOrgData/division | |||||
employeeType | |||||
externalUserState | |||||
faxNumber | |||||
givenName | |||||
identities/any(i:i/issuer) | |||||
imAddresses/any (p:p) | |||||
infoCatalogs/any(p:p) | |||||
isResourceAccount | |||||
jobTitle | |||||
licenseDetails/any (l:l/id) | |||||
mailNickname | |||||
manager/id | |||||
mobilePhone | |||||
oauth2PermissionGrants/任何 (o:o/id) | |||||
officeLocation | |||||
onPremisesExtensionAttributes/extensionAttribute1 | |||||
onPremisesExtensionAttributes/extensionAttribute10 | |||||
onPremisesExtensionAttributes/extensionAttribute11 | |||||
onPremisesExtensionAttributes/extensionAttribute12 | |||||
onPremisesExtensionAttributes/extensionAttribute13 | |||||
onPremisesExtensionAttributes/extensionAttribute14 | |||||
onPremisesExtensionAttributes/extensionAttribute15 | |||||
onPremisesExtensionAttributes/extensionAttribute2 | |||||
onPremisesExtensionAttributes/extensionAttribute3 | |||||
onPremisesExtensionAttributes/extensionAttribute4 | |||||
onPremisesExtensionAttributes/extensionAttribute5 | |||||
onPremisesExtensionAttributes/extensionAttribute6 | |||||
onPremisesExtensionAttributes/extensionAttribute7 | |||||
onPremisesExtensionAttributes/extensionAttribute8 | |||||
onPremisesExtensionAttributes/extensionAttribute9 | |||||
onPremisesImmutableId | |||||
onPremisesLastSyncDateTime | |||||
onPremisesProvisioningErrors/$count | |||||
onPremisesProvisioningErrors/any(o:o/category) | |||||
onPremisesProvisioningErrors/any(o:o/propertyCausingError) | |||||
onPremisesSamAccountName | |||||
onPremisesSecurityIdentifier | |||||
onPremisesSyncEnabled | |||||
otherMails/$count | |||||
otherMails/any (p:p) | |||||
ownedObjects/$count | |||||
passwordPolicies | |||||
passwordProfile/forceChangePasswordNextSignIn | |||||
passwordProfile/forceChangePasswordNextSignInWithMfa | |||||
postalCode | |||||
preferredLanguage | |||||
provisionedPlans/any(p:p/provisioningStatus) | |||||
provisionedPlans/any(p:p/service) | |||||
proxyAddresses/$count | |||||
proxyAddresses/any(p:p) | |||||
scopedRoleMemberOf/any (s:s/id) | |||||
showInAddressList | |||||
state | |||||
streetAddress | |||||
surname | |||||
usageLocation | |||||
userPrincipalName | |||||
userType |
下表显示了对用户对象上 by 扩展属性的支持$filter
。
扩展类型 | eq | startsWith | eq null |
---|---|---|---|
onPremisesExtensionAttributes 1-15 | |||
架构扩展 | |||
开放扩展 | |||
目录扩展 |
针对目录对象的高级查询的错误处理
仅支持使用高级查询参数对目录对象进行计数。 如果未指定 ConsistencyLevel=eventual
标头,则在使用 $count
URL 段时,请求将返回错误或以无提示方式忽略 $count
查询参数(?$count=true
)。
GET https://graph.microsoft.com/v1.0/users/$count
{
"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"
}
}
}
对于目录对象, $search
仅适用于高级查询。 如果未指定 ConsistencyLevel 标头,则请求将返回错误。
GET https://graph.microsoft.com/v1.0/applications?$search="displayName:Browser"
{
"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"
}
}
}
如果 URL 中的属性或查询参数仅在高级查询中受支持,但缺少 ConsistencyLevel 标头或 $count=true
查询字符串,则请求将返回错误。
GET https://graph.microsoft.com/v1.0/users?$filter=endsWith(mail,'@outlook.com')
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "Unsupported Query.",
"innerError": {
"date": "2021-05-18T19:12:36",
"request-id": "63f2093c-399c-4350-9609-3ce9b62abe3c",
"client-request-id": "e60ed0ba-df5d-e190-f056-f9c0318456d7"
}
}
}
如果尚未为某个属性编制索引以支持查询参数,即使指定了高级查询参数,请求也将返回错误。
GET https://graph.microsoft.com/beta/groups?$filter=createdDateTime ge 2021-11-01&$count=true
ConsistencyLevel: eventual
{
"error": {
"code": "Request_UnsupportedQuery",
"message": "The request uses a filter property that is not indexed",
"innerError": {
"date": "2021-06-10T19:32:01",
"request-id": "5625ba13-0c9f-4fce-a853-4b52f3e0bd09",
"client-request-id": "76fe4cd8-df3a-f8c3-659b-594274b6bb31"
}
}
}
但是,值得注意的是请求中指定的查询参数可能会自行失败。
不支持的查询参数以及不支持的查询参数组合的情况就是如此。
在这些情况下,应检查请求返回的数据,以确定指定的查询参数是否具有所需的效果。 例如,在下面的示例中,即使查询成功, @odata.count
参数也缺失。
GET https://graph.microsoft.com/v1.0/users?$count=true
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"
},
]
}