使用 OData Analytics 定义基本查询

Azure DevOps Services |Azure DevOps Server |Azure DevOps Server 2022 |Azure DevOps Server 2020

可以使用适用于 Azure DevOps 的分析来构造 OData 查询,以返回感兴趣的数据。 可以在浏览器或客户端软件(如 Excel 或 Power BI)中运行这些查询。

本文重点介绍用于检索 Azure Boards 工作跟踪实体集的查询,但原则适用于查询其他实体集。 有关详细信息,请参阅构造 OData 查询用于分析Azure Boards Analytics 的元数据参考

本教程介绍如何:

  • 定义返回项目计数的查询,可以选择是否包含其数据。
  • 选择特定属性以返回数据。
  • 按特定属性筛选数据。
  • 返回 标识区域路径迭代路径等导航属性的数据。
  • 使用 expand 子句和嵌套 expand 语句。
  • 查询日期范围。
  • 使用选项 orderby 对结果进行排序。

注意

Azure DevOps Services 中所有服务的生产中会自动启用并支持 Analytics 服务。 Power BI 集成 和对 Analytics 服务的 OData 源 的访问权限现已普遍可用。 鼓励您使用 Analytics OData 提要并提供反馈。

可用数据依赖于版本。 OData API 的最新支持版本是 v2.0,最新的预览版本是 v4.0-preview。 有关详细信息,请参阅 OData API 版本控制

注意

Azure DevOps Server 2020 及更高版本的所有新项目集合都会自动安装并支持 Analytics 服务。 Power BI 集成 和对 Analytics 服务的 OData 源 的访问权限现已普遍可用。 鼓励您使用 Analytics OData 提要并提供反馈。 如果从 Azure DevOps Server 2019 升级,可以在升级期间安装 Analytics 服务。

可用数据依赖于版本。 OData API 的最新支持版本是 v2.0,最新的预览版本是 v4.0-preview。 有关详细信息,请参阅 OData API 版本控制

先决条件

类别 要求
访问级别 - 项目成员
- 至少 基本 访问权限。
权限 默认情况下,项目成员有权查询 Analytics 和创建视图。 有关服务和功能启用和常规数据跟踪活动的其他先决条件的详细信息,请参阅 访问 Analytics 的权限和先决条件。

注意

当运行查询的用户无法访问所有项目时,跨项目查询将失败。 有关要求的详细信息,请参阅项目和组织范围的查询

注意

本文中的 OData 查询使用为 Azure DevOps Services https://analytics.dev.azure.com/定义的查询 URL。 在查询中替换你自己的组织和项目名称,以熟悉查询 OData。

对于本地服务器,可以使用基于服务器和项目集合 https://<servername>/<ProjectCollectionName>/的 URL 构造类似的查询。 有关详细信息,请参阅 为 Analytics 构造 OData 查询

获取条目计数

若要仅返回在组织或项目中定义的项或实体计数而不包括其他信息,请应用 $apply=aggregate($count as Count) 查询选项。 以下查询返回组织中的项目、工作项、区域路径和用户数。

https://analytics.dev.azure.com/<OrganizationName>/_odata/v4.0-preview/Projects?$apply=aggregate($count as Count)
https://analytics.dev.azure.com/<OrganizationName>/_odata/v4.0-preview/WorkItems?$apply=aggregate($count as Count)
https://analytics.dev.azure.com/<OrganizationName>/_odata/v4.0-preview/Areas?$apply=aggregate($count as Count)
https://analytics.dev.azure.com/<OrganizationName>/_odata/v4.0-preview/Users?$apply=aggregate($count as Count)

上述查询将返回如下示例结果,适用于 fabrikam 组织中的项目:

{
  "@odata.context": "https://analytics.dev.azure.com/fabrikam/_odata/v4.0-preview/$metadata#Projects(Count)",
  "value": [
    {
      "@odata.id": null,
      "Count": 16
    }
  ]
}

获取项及其数据的计数

若要返回项的计数及其选定数据,请在select语句中指定$count=true查询选项。 以下查询返回项目中定义的工作项、区域路径和用户的计数,以及指定的属性。 有关有效属性,请参阅 Azure Boards Analytics 的 元数据参考和 日历日期、项目和 Azure DevOps Analytics 的用户元数据参考。

https://analytics.dev.azure.com/<OrganizationName>/<ProjectName>/_odata/v4.0-preview/WorkItems?$count=true&$select=WorkItemId,Title,WorkItemType 
https://analytics.dev.azure.com/<OrganizationName>/<ProjectName>/_odata/v4.0-preview/Areas?$count=true&$select=AreaName,AreaPath 
https://analytics.dev.azure.com/<OrganizationName>/<ProjectName>/_odata/v4.0-preview/Users?$count=true&$select=UserName,UserEmail

注意

若要返回为指定实体类型定义的所有属性,可以使用 $count=true 而不带有 select 子句。 但是,如果未包含 $select$apply 子句,则会收到警告,例如 VS403507: The specified query does not include a $select or $apply clause which is recommended for all queries. Details on recommended query patterns are available here: https://go.microsoft.com/fwlink/?linkid=861060。 为了避免遇到使用限制,请始终在查询中包括$select$apply子句。

例如,以下查询请求 Fabrikam Fiber 项目中用户的计数和用户名

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/Users?$count=true&$select=UserName

该查询返回用户的计数,包含其用户名5

{
  "@odata.context": "https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/$metadata#Users(UserName)",
  "@odata.count": 5,
  "value": [
    {
      "UserName": "Microsoft.VisualStudio.Services.TFS"
    },
    {
      "UserName": "fabrikamfiber1@hotmail.com"
    },
    {
      "UserName": "Jamal Hartnett"
    },
    {
      "UserName": "fabrikamfiber5@hotmail.com"
    },
    {
      "UserName": "fabrikamfiber2@hotmail.com"
    }
  ]
}

选择特定属性或字段

若要返回特定属性或工作项字段,请添加一个 $select 指定属性名称的子句。 例如,若要返回 工作项 ID工作项类型标题和工作项 状态 ,请将子 $select=WorkItemId,WorkItemType,Title,State 句添加到查询。

$select 子句指定与命名字段对应的属性名称。 OData 查询中的属性名称不仅需要注意间距,还需要注意大小写。 尽管 工作项 ID 等属性显示名称可以包含空格,但正式属性名称不能包含空格。

有关属性名称和标签的详细信息,请参阅 Azure Boards 的元数据参考。 若要了解如何标记自定义字段属性,请参阅 “自定义属性”。

以下示例查询请求获取 Fabrikam Fiber 项目中,排名前三的工作项的工作项 ID、标题和状态。

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/WorkItems?$select=WorkItemId,WorkItemType,Title,State&$top=3

Analytics 返回以下数据。

{
  "@odata.context": "https://analytics.dev.azure.com/fabrikamprime/Fabrikam%20Fiber/_odata/v4.0-preview/$metadata#WorkItems(WorkItemId,WorkItemType,Title,State)",
  "value": [
    {
      "WorkItemId": 31,
      "Title": "About screen",
      "WorkItemType": "Task",
      "State": "New"
    },
    {
      "WorkItemId": 30,
      "Title": "Change background color",
      "WorkItemType": "Task",
      "State": "Active"
    },
    {
      "WorkItemId": 32,
      "Title": "Standardize on form factors",
      "WorkItemType": "Task",
      "State": "Active"
    }
  ]
}

筛选数据

若要筛选实体集以返回特定项,请添加一个 $filter 指定项必须满足的条件的子句。 以下筛选器子句仅返回处于进行中状态的功能工作项类型。

/WorkItems?$filter=WorkItemType eq 'Feature' and State eq 'In Progress'

以下示例查询指定仅返回处于正在进行状态的功能工作项的工作项 ID工作项类型标题状态

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/WorkItems?$select=WorkItemId,Title,AssignedTo,State&$filter=WorkItemType eq 'Feature' and State eq 'In Progress'

指定多个筛选器子句

可以在单个and子句中使用or$select指定多个筛选器。 例如,以下查询指定了 用户情景Bug 或自定义类型 Backlog Work 类型(处于 “新建”、“ 已提交”或 “活动 ”状态)的工作项中的多个字段。 使用括号根据需要对筛选器子句进行分组。

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/WorkItems?$select=WorkItemId,Title,AssignedTo,State&$filter=(WorkItemType eq 'User Story' or WorkItemType eq 'Bug' or WorkItemType eq 'Backlog Work') and (State eq 'New' or State eq 'Committed' or State eq 'Active')

查询返回的数据如下:


{
  "@odata.context": "https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/$metadata#WorkItems(WorkItemId,Title,AssignedTo,State)",
  "value": [
    {
      "WorkItemId": 210,
      "Title": "Slow response on form",
      "State": "Active"
    },
    ...
    {
      "WorkItemId": 160,
      "Title": "Game store testing",
      "State": "New"
    }
  ]
}

还可以在 $select 子句中应用各种函数,例如 containsstartswithendswith。 请参阅 支持的函数

查询区域路径或迭代路径属性

若要查找AreaSKIterationSK特定区域路径或迭代路径的其他属性,请使用以下查询。

返回特定区域路径的 AreaSK 值

以下查询请求 AreaSKFabrikam Fiber\Production Planning\Web 区域路径定义的属性。 若要查看 Areas 实体集的其他已定义属性,请参阅 “区域”。

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/Areas?$filter=AreaPath eq 'Fabrikam Fiber\Production Planning\Web' &$select=AreaSK

查询返回以下数据。

{
  "@odata.context": "https://analytics.dev.azure.com/fabrikamprime/Fabrikam%20Fiber/_odata/v4.0-preview/$metadata#Areas(AreaSK)",
  "value": [
    {
      "AreaSK": "aaaaaaaa-0000-1111-2222-bbbbbbbbbbbb"
    }
  ]
}

返回特定迭代路径的 IterationSK

以下查询返回 IterationSKFabrikam Fiber\3Week Sprints\Sprint 3 迭代路径定义的属性。 若要查看 迭代 实体集的其他已定义属性,请参阅 “迭代”。

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/Iterations?$filter=IterationPath eq 'Fabrikam Fiber\Release 1\Sprint 3' &$select=IterationSK

按导航属性进行筛选

导航属性表示实体类型之间的关系。 将导航属性指定为筛选条件的一部分时,必须指定导航属性的完整路径。 例如,以下子句基于为导航属性指定的迭代路径筛选工作项。

/WorkItems?$filter=Iteration/IterationPath eq 'Project Name\Iteration 1'

Iteration 是导航属性, IterationPath 是感兴趣的字段。 Iteration/IterationPathIterationPath 属性的完整路径。

以下示例通过指定完整路径Fabrikam Fiber\3Week Sprints\Sprint 3来查询迭代路径下Iteration/IterationPath前五个工作项中的数据。

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/WorkItems?$top=5&$filter=Iteration/IterationPath eq 'Fabrikam Fiber\3Week Sprints\Sprint 3'&$select=WorkItemId, WorkItemType, Title, State&$orderby=WorkItemId asc

前面的示例查询不返回 Iteration 数据,因为 Iteration 是相关实体。 导航属性的属性,例如 IdentityAreaIteration,无法通过使用 $select 语句直接访问。 必须使用 $expand 语句从相关实体返回数据。

/WorkItems?$select=WorkItemId,WorkItemType,Title,State&$filter=WorkItemId eq 00000&$expand=Iteration

以下示例查询请求与工作项 ID 480关联的信息,包括展开 Iteration 的数据。

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/WorkItems?$filter=WorkItemId eq 480&$select=WorkItemId,WorkItemType,Title,State&$expand=Iteration

查询返回以下数据,其中包括展开 Iteration 属性中的所有字段。

{
  "@odata.context": "https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/$metadata#WorkItems(WorkItemId,WorkItemType,Title,State,Iteration)",
  "value": [
    {
      "WorkItemId": 480,
      "Title": "Add animated emoticons",
      "WorkItemType": "User Story",
      "State": "New",
      "Iteration": {
        "ProjectSK": "bbbbbbbb-1111-2222-3333-cccccccccccc",
        "IterationSK": "cccccccc-2222-3333-4444-dddddddddddd",
        "IterationId": "cccccccc-2222-3333-4444-dddddddddddd",
        "IterationName": "Sprint 3",
        "Number": 276,
        "IterationPath": "Fabrikam Fiber\\3Week Sprints\\Sprint 3",
        "StartDate": "2025-12-04T00:00:00-12:00",
        "EndDate": "2025-12-25T23:59:59.999-12:00",
        "IterationLevel1": "Fabrikam Fiber",
        "IterationLevel2": "3Week Sprints",
        "IterationLevel3": "Sprint 3",
        "IterationLevel4": null,
        "IterationLevel5": null,
        "IterationLevel6": null,
        "IterationLevel7": null,
        "IterationLevel8": null,
        "IterationLevel9": null,
        "IterationLevel10": null,
        "IterationLevel11": null,
        "IterationLevel12": null,
        "IterationLevel13": null,
        "IterationLevel14": null,
        "Depth": 2,
        "IsEnded": false,
        "AnalyticsUpdatedDate": "2025-10-22T17:28:14.7166667Z"
      }
    }
  ]
}

在 expand 语句中使用 select

如果展开的属性返回的数据多于所需数据,请针对该属性添加 $select 语句。

/WorkItems?$select=WorkItemId,WorkItemType,Title,State&$filter=WorkItemId eq 00000&$expand=Iteration($select=Name,IterationPath)

例如,以下示例查询仅从展开的Iteration属性中选择IterationNameIterationPath数据。

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/WorkItems?$filter=WorkItemId eq 480&$select=WorkItemId,WorkItemType,Title,State&$expand=Iteration($select=IterationName,IterationPath)

查询返回以下数据。

{
  "@odata.context": "https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/$metadata#WorkItems(WorkItemId,WorkItemType,Title,State,Iteration(IterationName,IterationPath))",
  "value": [
    {
      "WorkItemId": 480,
      "Title": "Add animated emoticons",
      "WorkItemType": "User Story",
      "State": "New",
      "Iteration": {
        "IterationName": "Sprint 3",
        "IterationPath": "Fabrikam Fiber\\3Week Sprints\\Sprint 3"
      }
    }
  ]
}

下表显示了如何使用 $expand$select 子句在导航属性中选择多个字段。 例如,您使用返回导航属性中“用户名称”字段的“已分配”属性

类型字段 引用的属性 示例子句
日期时间 DateSK $expand=CreatedDate($select=Date)
$expand=CreatedDate($select=WeekStartingDate)
标识 UserSK $expand=AssignedTo($select=UserName)
$expand=AssignedTo($select=UserEmail)
区域 AreaSK $expand=Area($select=AreaName)
$expand=Area($select=AreaPath)
迭代 IterationSK $expand=Iteration($select=IterationName)
$expand=Iteration($select=IterationPath)
$expand=Iteration($select=StartDate)
集成 ProjectSK $expand=Project($select=ProjectName)
团队 TeamSK $expand=Teams($select=TeamName)

可以使用逗号分隔的列表指定要在单个 $expand 子句中展开的多个属性。

$expand=AssignedTo($select=UserName),Iteration($select=IterationPath),Area($select=AreaPath)

使用嵌套扩展语句

可以使用嵌套的 OData $expand 语句。 例如,以下查询使用嵌套 $expand 语句来显示迭代所使用的项目。

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/WorkItems?$filter=WorkItemId eq 480&$select=WorkItemId,WorkItemType,Title,State&$expand=Iteration($expand=Project)

该查询返回以下数据:

{
  "@odata.context": "https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/$metadata#WorkItems(WorkItemId,WorkItemType,Title,State,Iteration)",
  "value": [
    {
      "WorkItemId": 480,
      "Title": "Add animated emoticons",
      "WorkItemType": "User Story",
      "State": "New",
      "Iteration": {
        "ProjectSK": "bbbbbbbb-1111-2222-3333-cccccccccccc",
        "IterationSK": "cccccccc-2222-3333-4444-dddddddddddd",
        "IterationId": "cccccccc-2222-3333-4444-dddddddddddd",
        "IterationName": "Sprint 3",
        "Number": 276,
        "IterationPath": "Fabrikam Fiber\\3Week Sprints\\Sprint 3",
        "StartDate": "2025-12-04T00:00:00-12:00",
        "EndDate": "2025-12-25T23:59:59.999-12:00",
        "IterationLevel1": "Fabrikam Fiber",
        "IterationLevel2": "3Week Sprints",
        "IterationLevel3": "Sprint 3",
        "IterationLevel4": null,
        "IterationLevel5": null,
        "IterationLevel6": null,
        "IterationLevel7": null,
        "IterationLevel8": null,
        "IterationLevel9": null,
        "IterationLevel10": null,
        "IterationLevel11": null,
        "IterationLevel12": null,
        "IterationLevel13": null,
        "IterationLevel14": null,
        "Depth": 2,
        "IsEnded": false,
        "AnalyticsUpdatedDate": "2025-10-22T17:28:14.7166667Z",
        "Project": {
          "ProjectSK": "bbbbbbbb-1111-2222-3333-cccccccccccc",
          "ProjectId": "bbbbbbbb-1111-2222-3333-cccccccccccc",
          "ProjectName": "Fabrikam Fiber",
          "AnalyticsUpdatedDate": "2025-10-28T20:27:13.5833333Z",
          "ProjectVisibility": "Private"
        }
      }
    }
  ]
}

可以添加$select语句,例如从Iteration中仅返回IterationNameIterationPath

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/WorkItems?$filter=WorkItemId eq 480&$select=WorkItemId,WorkItemType,Title,State&$expand=Iteration($select=IterationName,IterationPath;$expand=Project)

此查询返回以下数据:

{
  "@odata.context": "https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/$metadata#WorkItems(WorkItemId,WorkItemType,Title,State,Iteration(IterationName,IterationPath,Project))",
  "value": [
    {
      "WorkItemId": 480,
      "Title": "Add animated emoticons",
      "WorkItemType": "User Story",
      "State": "New",
      "Iteration": {
        "IterationName": "Sprint 3",
        "IterationPath": "Fabrikam Fiber\\3Week Sprints\\Sprint 3",
        "Project": {
          "ProjectId": "bbbbbbbb-1111-2222-3333-cccccccccccc",
          "ProjectId": "bbbbbbbb-1111-2222-3333-cccccccccccc",
          "ProjectName": "Fabrikam Fiber",
          "AnalyticsUpdatedDate": "2025-10-28T20:27:13.5833333Z",
          "ProjectVisibility": "Private"
        }
      }
    }
  ]
}

结果仅显示IterationNameIterationPath来自Iteration,并作为Iteration结果中的一个嵌套对象Project

注意

在将$expand子句嵌套到$select语句中时,必须在嵌套$expand之前使用分号;以避免错误。

查询日期范围

以下示例查询返回上次 更改日期 大于或等于 2025 年 1 月 1 日的工作项。

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/WorkItems?$select=WorkItemId,WorkItemType,Title,State&$filter=ChangedDate ge 2025-01-01Z

以下示例查询返回工作项,其上次 更改日期 发生在 2025 年 10 月 31 日至 11 月 7 日的一周。

https://analytics.dev.azure.com/fabrikam/Fabrikam%20Fiber/_odata/v4.0-preview/WorkItems?$select=WorkItemId,WorkItemType,Title,State&$filter=ChangedDate ge 2025-10-31Z&ChangedDate le 2025-11-07Z

对结果进行排序

请指定 $orderby 选项以对结果进行排序,或指定返回结果的顺序。 可以使用关键字ascdesc或按升序或降序排序。 下表展示了一些示例。

排序依据
工作项 ID /WorkItems?$orderby=WorkItemId
工作项 ID 降序 /WorkItems?$orderby=WorkItemId desc
工作项类型和状态 /WorkItems?$orderby=WorkItemType,State

后续步骤