Azure DevOps에 대한 OData Analytics 쿼리 지침

Azure DevOps Services | Azure DevOps Server 2022 - Azure DevOps Server 2019

확장 개발자는 Azure DevOps용 Analytics에 대한 효율적인 OData 쿼리를 디자인하기 위해 이 문서에 제공된 지침에 따라 이점을 얻을 수 있습니다. 다음 지침에 따라 쿼리가 실행 시간과 리소스 사용량에 대해 좋은 성능을 갖도록 할 수 있습니다. 이러한 지침을 준수하지 않는 쿼리는 긴 보고서 대기 시간, 허용된 리소스 사용량을 초과하는 쿼리 또는 서비스 차단으로 인해 성능이 저하될 수 있습니다.

참고 항목

Analytics 서비스는 모든 Azure DevOps Services에 대해 프로덕션에서 자동으로 사용하도록 설정되고 지원됩니다. Analytics Service의 OData 피드에 대한 Power BI 통합 및 액세스는 일반적으로 사용할 수 있습니다. 이를 사용하고 피드백을 제공하는 것이 좋습니다. 사용 가능한 데이터는 버전에 따라 다릅니다. 지원되는 최신 버전은 v2.0최신 미리 보기 버전입니다 v4.0-preview. 자세한 내용은 OData API 버전 관리를 참조 하세요.

참고 항목

Analytics 서비스는 Azure DevOps Server 2020 이상 버전의 모든 새 프로젝트 컬렉션에 대해 프로덕션에 자동으로 설치되고 지원됩니다. Analytics Service의 OData 피드에 대한 Power BI 통합 및 액세스는 일반적으로 사용할 수 있습니다. 이를 사용하고 피드백을 제공하는 것이 좋습니다. Azure DevOps Server 2019에서 업그레이드한 경우 업그레이드 중에 Analytics 서비스를 설치할 수 있습니다.

사용 가능한 데이터는 버전에 따라 다릅니다. 지원되는 최신 버전은 v2.0최신 미리 보기 버전입니다 v4.0-preview. 자세한 내용은 OData API 버전 관리를 참조 하세요.

참고 항목

Analytics 서비스는 Azure DevOps Server 2019용 미리 보기로 제공됩니다. 프로젝트 컬렉션에 사용하도록 설정하거나 설치할 수 있습니다. Power BI 통합 및 Analytics Service의 OData 피드에 대한 액세스는 미리 보기로 제공됩니다. 이를 사용하고 피드백을 제공하는 것이 좋습니다.

사용 가능한 데이터는 버전에 따라 다릅니다. 지원되는 최신 버전은 v2.0최신 미리 보기 버전입니다 v4.0-preview. 자세한 내용은 OData API 버전 관리를 참조 하세요.

이러한 지침은 DO, CONSIDER, AVOIDDON'T라는 용어를 접두사로 하는 권장 사항입니다. Analytics에서 적용되는 제한 규칙에는 [BLOCKED] 접두사를 포함합니다. 서로 다른 솔루션 간의 장차를 이해해야 합니다. 특정 상황에서는 하나 이상의 지침을 위반하도록 강제하는 데이터 요구 사항이 있을 수 있습니다. 이러한 경우는 드물어야 합니다. 이러한 결정에 대한 명확하고 설득력 있는 이유가 있는 것이 좋습니다.

이 문서에 표시된 예제는 Azure DevOps Services URL을 기반으로 합니다. 온-프레미스 버전에 대체를 사용합니다.

https://{servername}:{port}/tfs/{OrganizationName}/{ProjectName}/_odata/{version}/

오류와 경고 메시지

✔️ OData 응답 경고 검토

실행하는 각 쿼리는 미리 정의된 규칙 집합에 대해 검사 가져옵니다. 위반은 다음 @vsts.warningsOData 응답을 반환합니다. 쿼리를 개선하는 방법에 대한 현재 및 상황에 맞는 정보를 제공하므로 이러한 경고를 검토합니다.

{
  "@odata.context": "https://{OrganizationName}.tfsallin.net/_odata/v1.0/$metadata#WorkItems",
  "@vsts.warnings": [
    "The specified query does not include a $select or $apply clause which is recommended for all queries."
  ],
  ...
}

✔️ OData 오류 메시지 검토

OData 오류 규칙을 위반하는 쿼리는 400(잘못된 요청) 상태 코드로 실패한 응답을 생성합니다. 연결 메시지는 속성 내에 @vsts.warnings 표시되지 않습니다. 대신 JSON 응답의 message 속성에 오류 메시지를 생성합니다.

{
  "error": {
  "code": "0",
  "message": "The query specified in the URI is not valid. The Snapshot tables in Analytics are intended to be used only in an aggregation."
  }
}

제한 사항

해야 할 일

Consider

차단됨

사용하지 말아야 할 용어

✔️ DO 쿼리를 액세스 권한이 있는 프로젝트로 제한

쿼리가 액세스할 수 없는 프로젝트의 데이터를 대상으로 하는 경우 쿼리는 "프로젝트 액세스 거부" 메시지를 반환합니다. 액세스 권한이 있는지 확인하려면 뷰 분석 권한이 쿼리하는 모든 프로젝트에 대해 허용으로 설정되어 있는지 확인합니다. 자세한 내용은 분석에 액세스하는 데 필요한 권한을 참조 하세요.

프로젝트에 액세스할 수 없는 경우 다음 메시지가 표시됩니다.

쿼리 결과에는 액세스 권한이 없는 하나 이상의 프로젝트에 데이터가 포함됩니다. 하나 이상의 프로젝트 필터를 추가하여 'WorkItems' 엔터티에서 액세스할 수 있는 프로젝트를 지정합니다. $expand 또는 탐색 속성을 사용하는 경우 해당 엔터티에 프로젝트 필터가 필요합니다.

이 문제를 해결하려면 프로젝트 필터를 명시적으로 추가하거나 이 문서의 뒷부분에 설명된 대로 프로젝트 범위 엔드포인트 를 사용할 수 있습니다.

예를 들어 다음 쿼리는 명명 {projectSK1}{projectSK2}프로젝트에 속하는 작업 항목을 가져옵니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=ProjectSK eq {projectSK1} or ProjectSK eq {projectSK2}
  &$select=WorkItemId, Title

✔️ 확장에 $expand 액세스할 수 없는 다른 프로젝트에 데이터를 포함할 수 있는 경우 절 내에 프로젝트 필터를 지정하세요.

탐색 속성을 확장하면 액세스할 수 없는 다른 프로젝트의 데이터를 참조하게 될 가능성이 있습니다. 액세스할 수 없는 데이터를 참조하는 경우 이전에 나열된 것과 동일한 오류 메시지가 표시됩니다. "쿼리 결과에 하나 이상의 프로젝트에 데이터가 포함됩니다...". 마찬가지로 확장된 데이터를 제어하는 명시적 프로젝트 필터를 추가하여 이 문제를 해결할 수 있습니다.

단순 탐색 속성에 대한 일반 $filter 절에서 이 작업을 수행할 수 있습니다. 예를 들어 다음 쿼리는 링크와 해당 대상이 동일한 프로젝트에 있는 위치를 명시적으로 묻 WorkItemLinks 습니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemLinks?
  $filter=ProjectSK eq {projectSK} and TargetWorkItem/ProjectSK eq {projectSK}
  &$select=LinkTypeReferenceName, SourceWorkItemId, TargetWorkItemId
  &$expand=TargetWorkItem($select=WorkItemId, Title)

대신 절에서 필터를 이동하여 옵션을 $expand 확장할 $filter 수 있습니다. 그러나 쿼리의 의미 체계를 변경합니다. 예를 들어 다음 쿼리는 지정된 프로젝트에서 모든 링크를 가져오고 동일한 프로젝트에 있는 경우에만 조건부로 대상을 확장합니다. 유효하지만 이 방법은 속성이 확장되지 않았거나 필터링되었기 때문에 null 확장되지 않는지 여부를 확인하기 어려울 수 있으므로 혼동을 일으킬 수 있습니다. 이 특정 동작이 실제로 필요한 경우에만 이 솔루션을 사용합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemLinks?
  $filter=ProjectSK eq {projectSK}
  &$select=LinkTypeReferenceName, SourceWorkItemId, TargetWorkItemId
  &$expand=TargetWorkItem($filter=ProjectSK eq {projectSK}; $select=WorkItemId, Title)

$filter 확장 옵션은 엔터티 집합과 같은 ChildrenWorkItems 확장 컬렉션 속성을 사용할 때 유용합니다. 예를 들어 다음 쿼리는 지정된 프로젝트의 모든 작업 항목을 동일한 프로젝트에 속한 모든 자식과 함께 반환합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=ProjectSK eq {projectSK}
  &$select=WorkItemId, Title
  &$expand=Children($filter=ProjectSK eq {projectSK}; $select=WorkItemId, Title)

다음 속성 중 하나를 확장하면 필터를 지정합니다.

  • WorkItems 엔터티 집합: Parent, Children
  • WorkItemLinks 엔터티 집합: TargetWorkItem.

✔️ 프로젝트 범위 엔드포인트를 사용하여 쿼리하는 것이 좋습니다.

단일 프로젝트의 데이터에 관심이 있는 경우 프로젝트 범위 OData 엔드포인트(/{ProjectName}/_odata/v1.0)를 사용하는 것이 좋습니다. 앞의 두 섹션에 설명된 문제를 방지하고 데이터를 하나의 프로젝트, 참조된 엔터티 집합 및 확장된 모든 탐색 속성으로 암시적으로 필터링합니다.

이 간소화를 통해 이전 섹션의 쿼리를 다음 형식으로 다시 작성할 수 있습니다. expand 절의 필터가 사라졌을 뿐만 아니라 기본 엔터티 집합에 대한 필터도 필요하지 않습니다.

https://analytics.dev.azure.com/{OrganizationName}/{ProjectName}/_odata/{version}//WorkItemLinks?
  &$select=LinkTypeReferenceName, SourceWorkItemId, TargetWorkItemId
  &$expand=TargetWorkItem($select=WorkItemId, Title)

작업 항목 자식에 대한 쿼리도 훨씬 짧고 간단합니다.

https://analytics.dev.azure.com/{OrganizationName}/{ProjectName}/_odata/{version}//WorkItems?
  &$select=WorkItemId, Title
  &$expand=Children($select=WorkItemId, Title)

포커스가 단일 프로젝트의 데이터인 경우에만 이 솔루션을 적용할 수 있습니다. 프로젝트 간 보고를 위해 이전 섹션에서 설명한 필터링 전략을 사용해야 합니다.

✔️ 쿼리가 사용 제한을 초과하는 경우 작업을 기다리거나 중지합니다.

많은 쿼리를 실행하거나 쿼리를 실행하기 위해 많은 리소스가 필요한 경우 서비스 제한을 초과하여 일시적으로 차단될 수 있습니다. 서비스 제한을 초과하는 경우 보내는 다음 쿼리가 동일한 오류 메시지와 함께 실패할 가능성이 있으므로 작업을 중지합니다.

네임스페이스 '{namespace}'의 리소스 '{resource}'를 초과하여 요청이 차단되었습니다.

속도 제한에 대한 자세한 내용은 속도 제한을 참조 하세요. 효율적인 OData 쿼리를 디자인하는 방법을 알아보려면 이 문서의 뒷부분에 있는 성능 지침을 참조하세요.

✔️ 쿼리가 시간 제한으로 실패하는 경우 작업을 기다리거나 중지합니다.

사용량 한도를 초과하는 것과 마찬가지로 쿼리가 시간 초과가 발생하는 경우 작업을 기다리거나 중지해야 합니다. 일시적인 문제를 알릴 수 있으므로 문제가 해결되었는지 확인하기 위해 한 번 다시 시도할 수 있습니다. 그러나 영구적 시간 제한은 쿼리가 실행하기에 너무 비싸다는 것을 나타냅니다. 추가 재시도는 사용 한도를 초과하면 차단됩니다.

TF400733: 요청이 취소되었습니다. 요청이 요청 시간 제한을 초과했습니다. 다시 시도하세요.

시간 제한은 쿼리에 최적화가 필요하다는 것을 나타냅니다. 효율적인 OData 쿼리를 디자인하는 방법을 알아보려면 이 문서의 뒷부분에 있는 성능 지침을 참조하세요.

❌[차단됨] 집계 이외의 다른 항목에는 스냅샷 엔터티를 사용하지 마세요.

접미사가 있는 Snapshot 스냅샷 엔터티 집합은 매일 스냅샷 모델링되므로 특별합니다. 이러한 엔터티를 사용하여 엔터티의 상태가 과거의 매일 끝에 있었던 것처럼 가져올 수 있습니다. 예를 들어 쿼리 WorkItemSnapshot 하고 단일 WorkItemId레코드로 필터링하는 경우 작업 항목이 만들어진 이후 매일 하나의 레코드를 얻게 됩니다. 이 모든 데이터를 직접 로드하는 것은 비용이 많이 들며 사용 제한을 초과하여 차단될 가능성이 큽니다. 그러나 이러한 엔터티에 대한 집계는 모두 허용되고 권장됩니다. 실제로 스냅샷 엔터티 집합은 집계 시나리오를 염두에 두고 설계되었습니다.

예를 들어 다음 쿼리는 2020년 1월에 어떻게 증가했는지 관찰하기 위해 날짜별로 작업 항목 수를 가져옵니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemSnapshot?
  $apply=
    filter(DateSK ge 20200101 and DateSK le 20200131)/
    groupby((DateSK), aggregate($count as Count))

집계에 대한 자세한 내용은 집계 데이터를 참조하세요.

✔️ 스냅샷 테이블을 집계할 때 절에 groupby DO 포함 또는 DateValue 열 포함 DateSK

모든 스냅샷 엔터티는 매일 스냅샷 테이블모델링되므로 그룹화 절에 항상 일 속성(DateSK또는DateValue) 중 하나를 포함해야 합니다. 그렇지 않으면 결과가 잘못 팽창된 것처럼 보일 수 있습니다.

예를 들어 속성별로 AssignedTo 만 그룹화 WorkItemSnapshot 하고 개수를 사용하여 집계하는 경우 사용자에게 할당된 작업 항목의 모든 개수에 각 할당이 활성화된 일 수를 곱합니다. 원하는 결과인 상황이 있을 수 있지만 이러한 경우는 드뭅니다.

❌ [차단됨] 엔터티 주소 지정을 위해 리소스 경로에 엔터티 키를 사용하지 마세요.

OData 구문은 해당 키를 URL 세그먼트에 직접 포함하여 특정 엔터티에 액세스하는 방법을 제공합니다. 자세한 내용은 OData 버전 4.0을 참조 하세요. 2부: URL 규칙 - 4.3 엔터티 주소 지정 OData는 이러한 주소 지정을 허용하지만 Analytics는 이를 차단합니다. 쿼리 내에 포함하면 다음 오류가 발생합니다.

URI에 지정된 쿼리가 잘못되었습니다. Analytics는 WorkItems(Id) 또는 WorkItem(Id)/AssignedTo와 같은 키 또는 속성 탐색을 지원하지 않습니다. PowerBI에서 해당 오류가 발생하는 경우 N+1 문제를 일으키는 잘못된 접기를 방지하려면 쿼리를 다시 작성하세요.

오류 메시지가 힌트로 표시되면 특정 클라이언트 도구가 직접 엔터티 주소 지정을 남용할 수 있습니다. 이러한 클라이언트는 단일 요청에서 모든 데이터를 로드하는 대신 각 엔터티를 독립적으로 쿼리하도록 선택할 수 있습니다. 이 방법은 요청 수가 많을 수 있으므로 권장되지 않습니다. 대신 다음 섹션에 설명된 대로 명시적 엔터티 주소 지정을 사용하는 것이 좋습니다.

✔️ DO 명시적으로 필터 절을 사용하여 엔터티 주소 지정

단일 엔터티에 대한 데이터를 가져오려면 엔터티 컬렉션과 동일한 방법을 사용하고 절에서 $filter 필터를 명시적으로 정의해야 합니다.

예를 들어 다음 쿼리는 식별자를 통해 단일 작업 항목을 가져옵니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=WorkItemId eq {id}
  &$select=WorkItemId, Title

이러한 필터에 포함해야 하는 속성을 잘 모르는 경우 메타데이터에서 조회할 수 있습니다. 메타데이터를 쿼리하는 URL 구성 요소인 Analytics에 대한 OData 쿼리 생성을 참조하세요. 속성은 .의 Key 요소에 있습니다 EntityType. 예를 들어 WorkItemIdRevision 엔터티의 키 열입니다 WorkItemRevision .

<EntityType Name="WorkItemRevision">
  <Key>
    <PropertyRef Name="WorkItemId"/>
    <PropertyRef Name="Revision"/>
  </Key>
  [...]
</EntityType>

❌[차단됨] 엔터티에서 WorkItem 확장 Revisions 안 함

분석 데이터 모델은 특정 유형의 확장을 허용하지 않습니다. 그 중 하나는 엔터티의 Revisions 컬렉션 속성 WorkItem 입니다. 이 속성을 확장하려고 하면 다음 오류 메시지가 표시됩니다.

URI에 지정된 쿼리가 잘못되었습니다. $expand 쿼리 옵션에서는 'Revisions' 속성을 사용할 수 없습니다.

이 제한은 다음 섹션에 설명된 대로 수정 버전을 WorkItemRevisions 가져오는 권장 솔루션을 모든 사용자가 사용하도록 장려하기 위해 적용되었습니다.

✔️ 엔터티 집합을 사용하여 WorkItemRevisions 지정된 작업 항목에 대한 모든 수정 버전을 로드합니다.

작업 항목 또는 작업 항목 컬렉션의 전체 기록을 가져올 때마다 사용합니다 WorkItemRevisions .

예를 들어 다음 쿼리는 식별자를 사용하여 작업 항목 {id} 의 모든 수정 버전을 반환합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemRevisions?
  $filter=WorkItemId eq {id}
  &$select=WorkItemId, Title

특정 조건과 일치하는 모든 작업 항목의 전체 기록에 관심이 있는 경우 탐색 속성에 필터 WorkItem 를 사용하여 표시합니다. 예를 들어 다음 쿼리는 현재 활성 상태인 모든 작업 항목의 수정 버전을 모두 가져옵니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemRevisions?
  $filter=WorkItem/State eq 'Active'
  &$select=WorkItemId, Title

❌ [차단됨] 고유 열을 그룹화하지 않음

그룹화 작업을 사용하여 레코드 수를 줄입니다. 절에 groupby 고유 열을 사용하면 문제가 발생하며 쿼리가 즉시 실패합니다. 실수로 이 상황이 발생하면 다음 오류 메시지가 표시됩니다.

이 쿼리의 groupby 절에 지정된 열 중 하나 이상이 권장되지 않습니다.

이 문제를 해결하려면 절에서 고유 열을 제거합니다 groupby .

❌ [차단됨] 집계 사용 countdistinct 안 함

OData에서 수행하는 경우에도 Analytics는 이 함수를 지원하지 countdistinct 않습니다. 향후 지원을 추가할 계획이지만 현재는 사용할 수 없습니다. 이 함수를 포함하는 쿼리는 다음 오류 메시지를 반환합니다.

집계를 사용하여 고유 개수를 적용하는 쿼리는 지원되지 않습니다.

❌ 산술 오버플로를 초래할 수 있는 집계 방지

드문 경우에서 집계 쿼리는 산술 오버플로에 문제가 발생할 수 있습니다. 예를 들어 작업 항목 엔터티와 같이 StackRank 합계를 계산할 수 없는 일부 숫자 속성을 합산할 때 발생할 수 있습니다. OData Extension for Data Aggregation 표준은 속성을 다른 형식으로 캐스팅하는 방법을 제공하지 않으므로 이 문제를 해결하는 유일한 방법은 집계에서 문제가 있는 속성을 제거하는 것입니다.

✔️ 긴 쿼리에 일괄 처리 엔드포인트 사용

긴 쿼리에 문제가 발생할 수 있습니다. 특히 다음과 같은 경우 문제가 발생할 수 있습니다.

  • 사용자 지정 필드가 많은 프로젝트를 쿼리합니다.
  • 쿼리는 프로그래밍 방식으로 생성됩니다.

전송 HTTP GET 된 OData 쿼리의 현재 제한은 3,000자입니다. 이 값을 초과하면 "404 찾을 수 없음" 응답이 반환됩니다.

HTTP/1.1 404 Not Found
Content-Length: 0

이 문제를 해결하려면 사양인 OData 버전 4.0에 설명된 대로 OData 일괄 처리 엔드포인트를 사용합니다. 1부: 프로토콜 - 11.7 일괄 처리 요청. Batch 기능은 주로 여러 작업을 단일 HTTP 요청 페이로드로 그룹화하도록 설계되었지만 쿼리 길이 제한에 대한 해결 방법으로 사용할 수도 있습니다. 요청을 보내 HTTP POST 면 임의의 길이의 쿼리를 전달할 수 있으며 서비스에서 올바르게 해석합니다.

❌ [차단됨] 여러 쿼리를 보내는 데 일괄 처리 엔드포인트를 사용하지 마세요.

일괄 처리 엔드포인트의 사용이 여러 요청의 일괄 처리를 처리하지 못하도록 제한합니다. 단일 요청에는 여전히 하나의 쿼리만 있을 수 있습니다. 여러 쿼리의 일괄 처리를 보내려고 하면 다음 오류 메시지와 함께 작업이 실패합니다. 유일한 해결 방법은 쿼리를 여러 요청으로 분할하는 것입니다.

분석은 현재 일괄 처리 메시지에 포함된 여러 작업의 처리를 지원하지 않습니다. Analytics는 POST 요청을 지원하기 위해 OData 일괄 처리를 사용하지만 작업을 단일 요청으로 제한해야 합니다.

❌ [차단됨] 800개 이상의 열을 생성하는 쿼리를 사용하지 마세요.

800개 이상의 열을 생성하는 쿼리를 제한합니다. 쿼리가 반환하는 열을 충분히 선택적이지 않은 경우 다음 오류 메시지가 표시될 수 있습니다.

VS403670: 지정된 쿼리는 허용되는 800개 열 제한보다 높은 'N' 열을 반환합니다. 열 수를 제한하려면 명시적 $select($expand 내 포함) 옵션을 사용하세요.

이 제한을 초과하지 않도록 쿼리에 $select 절을 추가하고 쿼리에서 작업을 $expand.

❌ 긴 쿼리를 만들지 마십시오.

긴 쿼리를 생성할 때마다 접근 방식을 평가하는 것이 좋습니다. 긴 쿼리(예: 복잡한 필터 또는 긴 속성 목록)가 필요한 많은 시나리오가 있지만 일반적으로 최적이 않은 디자인의 초기 표시기를 제공합니다.

쿼리에 많은 엔터티 키가 포함된 경우(예: WorkItemId eq {id 1} or WorkItemId eq {id 2} or ...) 다시 작성할 수 있습니다. 식별자를 전달하는 대신 동일한 엔터티 집합을 선택하는 다른 조건을 정의합니다. 경우에 따라 프로세스를 수정해야 할 수도 있지만(예: 새 필드 또는 태그 추가) 일반적으로 가치가 있습니다. 더 많은 추상 필터를 사용하는 쿼리는 기본 파악하기 쉽고 더 잘 작동할 가능성이 더 큽니다.

긴 쿼리를 생성하는 경향이 있는 또 다른 시나리오는 여러 개별 날짜(예 DateSK eq {dateSK 1} or DateSK eq {dateSK 2} or ...: )를 포함할 때 발생합니다. 더 추상적인 필터를 만드는 데 사용할 수 있는 다른 패턴을 찾습니다. 예를 들어 다음 쿼리는 월요일에 만든 모든 작업 항목을 반환합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedOn/DayOfWeek eq 2
  &$select=WorkItemId, Title, State

✔️ 날짜 열을 필터링할 때 표준 시간대 지정

표준 시간대(Edm.DateTimeOffset)는 조직의 표준 시간대 설정과 일치하는 오프셋을 사용하여 모든 날짜 및 시간 정보를 노출합니다. 이 데이터는 정확하고 간단하게 동시에 해석할 수 있습니다. 또 다른 미해결 결과는 모든 필터가 표준 시간대 정보를 전달해야 한다는 것입니다. 건너뛰면 다음 오류 메시지가 표시됩니다.

URI에 지정된 쿼리가 잘못되었습니다. 날짜/시간 오프셋이 지정되지 않았습니다. 이러한 형식 YYYY-MM-ddZ 중 하나를 사용하여 자정 이후의 모든 항목을 지정하거나 yyyy-MM-ddThh:mm-hh:mm(날짜 및 시간의 ISO 8601 표준 표현)을 사용하여 오프셋을 지정합니다.

이 문제를 해결하려면 표준 시간대 정보를 추가합니다. 예를 들어 조직이 "(UTC-08:00) 태평양 표준시(미국 및 캐나다)" 표준 시간대에 데이터를 표시하도록 구성되어 있다고 가정하면 다음 쿼리는 2020년 초부터 만든 모든 작업 항목을 가져옵니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedDate ge 2020-01-01T00:00:00-08:00
  &$select=WorkItemId, Title, State

동일한 솔루션은 양수 오프셋이 있는 표준 시간대에 대해 작동합니다. 그러나 더하기 문자(+)는 URI에 특별한 의미를 가지며 올바르게 처리해야 합니다. 문자를 사용하여 시작점으로 지정 2020-01-01T00:00:00+08:00+ 하면 다음 오류가 발생합니다.

URI에 지정된 쿼리가 잘못되었습니다. 'CreatedDate ge 2020-01-01T0000 08:00'의 위치 31에서 구문 오류입니다.

이 문제를 해결하려면 문자를 인코딩된 버전으로 바꿉 + 니다 %2B. 예를 들어 조직이 "(UTC+08:00) 베이징, 충칭, 홍콩, 우루무치" 표준 시간대에 데이터를 표시하도록 구성되어 있다고 가정하면 다음 쿼리는 2020년 초부터 생성된 모든 작업 항목을 반환합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedDate ge 2020-01-01T00:00:00%2B08:00
  &$select=WorkItemId, Title, State

다른 방법은 표준 시간대 정보를 유지하지 않으므로 날짜 서로게이트 키 속성을 사용하는 것입니다. 예를 들어 다음 쿼리는 조직의 설정에 관계없이 2020년 초부터 만든 모든 작업 항목을 반환합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedDateSK ge 20200101
  &$select=WorkItemId, Title, State

성능 지침

해야 할 일

사용하지 마세요.

Consider

사용하지 말아야 할 용어

✔️ DO 성능 지침 구현 효과 측정

성능 권장 사항과 마찬가지로 맹목적으로 구현해서는 안 됩니다. 대신 항상 기준을 캡처하고 변경 내용의 효과를 측정 합니다. 모든 지침은 특정 요구 사항 및 문제가 있는 분석 클라이언트와의 상호 작용을 기반으로 작성되었습니다. 이러한 권장 사항은 일반적인 것으로 간주되었으며 유사한 쿼리를 디자인하는 모든 사용자에게 유용할 수 있습니다. 그러나 드문 경우에서 지침에 따라 성능에 영향을 주지 않거나 부정적인 영향을 미칠 수 있습니다. 차이를 알아차리려면 측정해야 합니다. 이 경우 개발자 커뮤니티 포털에서 피드백을 제공합니다.

성능을 측정하는 많은 옵션이 있습니다. 가장 간단한 방법은 브라우저에서 동일한 쿼리의 두 버전을 직접 실행하는 것입니다. 개발자 도구에서 소요되는 시간을 관찰합니다. 예를 들어 Microsoft Edge F12 개발자 도구에서 네트워크 패널을 사용할 수 있습니다.) 또 다른 옵션은 Fiddler 웹 디버거 도구를 사용하여 이 정보를 캡처하는 것입니다.

접근 방식이 무엇이든 간에 두 쿼리를 여러 번 실행합니다. 예를 들어 쿼리를 각각 30번 실행하여 충분히 큰 샘플 집합을 만듭니다. 그런 다음 성능 특성을 파악합니다. 분석은 다중 테넌트 아키텍처를 따릅니다. 따라서 동시에 발생하는 다른 작업은 쿼리 기간에 영향을 줄 수 있습니다.

✔️ DO 집계 확장 사용

지금까지 쿼리 성능을 향상시키기 위해 수행할 수 있는 가장 좋은 방법은 집계 확장인 데이터 집계용 OData 확장을 사용하는 것입니다. 집계 확장을 사용하여 서비스에 데이터 서버 쪽을 요약하고 동일한 함수 클라이언트 쪽을 적용하여 가져올 수 있는 것보다 작은 응답을 반환하도록 요청합니다. 마지막으로 분석이 이러한 유형의 쿼리에 최적화되어 있으므로 사용합니다.

자세한 내용은 집계 데이터를 참조 하세요.

✔️ 절에 $select 열 지정

절에서 관심 있는 $select 열을 지정합니다. 분석은 Columnstore 인덱스 기술을 기반으로 합니다. 즉, 데이터는 스토리지이고 쿼리 처리는 열 기반입니다. 속성 집합을 줄이면 절에서 $select 참조하면 검색해야 하는 열 수를 줄이고 쿼리의 전반적인 성능을 향상시킬 수 있습니다.

예를 들어 다음 쿼리는 작업 항목의 열을 지정합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $select=WorkItemId, Title, State

참고 항목

Azure DevOps는 프로세스 사용자 지정을 지원합니다. 일부 관리자는 이 기능을 사용하고 수백 개의 사용자 지정 필드를 만듭니다. 절을 생략하면 쿼리는 $select 사용자 지정 필드를 포함한 모든 필드를 반환합니다.

✔️ 절 내 $expand 의 expand 옵션에 $select 열 지정

절 지침과 $select 마찬가지로 절 내의 expand 옵션에 $select 속성을 지정합니다 $expand . 잊기 쉽지만 생략하면 응답에 확장된 개체의 모든 속성이 포함됩니다.

예를 들어 다음 쿼리는 작업 항목과 해당 부모 모두에 대한 열을 지정합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $select=WorkItemId, Title, State
  &$expand=Parent($select=WorkItemId, Title, State)

✔️ 기록 작업 항목 데이터(WorkItemRevisions또는 WorkItemSnapshot 엔터티 집합)를 RevisedDateSK 쿼리할 때 필터 정의

기록 데이터를 쿼리할 때 가장 최근 기간(예: 30일, 90일)에 관심이 있을 수 있습니다. 작업 항목 엔터티가 구현되는 방식 때문에 뛰어난 성능을 얻기 위해 이러한 쿼리를 작성하는 편리한 방법이 있습니다. 작업 항목을 업데이트할 때마다 새 수정 내용이 만들어지고 이 작업이 System.RevisedDate 필드에 기록되므로 기록 필터에 적합합니다.

Analytics에서 수정된 날짜는 () 및 RevisedDateSK (Edm.DateTimeOffsetEdm.Int32) 속성에 RevisedDate 표시됩니다. 최상의 성능을 위해 후자를 사용합니다. 날짜 서로게이트 키 이며 수정 버전이 만들어졌거나 null 불완전한 활성 수정 버전에 대한 날짜를 나타냅니다. 포함 이후 {startDate} 의 모든 날짜를 원하는 경우 쿼리에 다음 필터를 추가합니다.

RevisedDateSK eq null or RevisedDateSK gt {startDateSK}

예를 들어 다음 쿼리는 2020년 초부터 매일의 작업 항목 수를 반환합니다. 열의 명백한 필터 DateSK 외에도 두 번째 필터가 있습니다 RevisedDateSK. 중복된 것처럼 보일 수 있지만 쿼리 엔진이 범위에 없는 수정 버전을 필터링하는 데 도움이 되며 쿼리 성능이 크게 향상됩니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/v1.0/WorkItemSnapshot?
  $apply=
    filter(DateSK gt 20200101)/
    filter(RevisedDateSK eq null or RevisedDateSK gt 20200101)/
    groupby(
      (DateValue), 
      aggregate($count as Count)
    )

참고 항목

번다운 위젯을 작업할 때 이 권장 사항을 내놓았습니다. 처음에는 필터만 DateSK 정의했지만 큰 데이터 세트가 있는 조직에 맞게 크기를 조정하기 위해 이 쿼리를 가져올 수 없었습니다. 쿼리 프로파일링 중에 수정 내용을 잘 필터링하지 않는 것으로 DateSK 나타났습니다. 필터 RevisedDateSK 를 추가한 후에만 대규모로 뛰어난 성능을 얻을 수 있었습니다.
~ 제품 팀

✔️ 긴 기간 동안 추세 쿼리에 매주 또는 매월 스냅샷 사용하세요.

기본적으로 모든 스냅샷 테이블은 매일 스냅샷 팩트 테이블로 모델링됩니다. 시간 범위를 쿼리하는 경우 매일 값을 가져옵니다. 장시간 범위는 많은 수의 레코드를 생성합니다. 이러한 높은 정밀도가 필요하지 않은 경우 매주 또는 매월 스냅샷 사용할 수 있습니다.

다른 필터 식을 사용하여 지정된 주 또는 월을 완료하지 않는 일을 제거할 수 있습니다. 이 시나리오를 IsLastDayOfPeriod 염두에 두고 Analytics에 추가된 속성을 사용합니다. 이 속성은 형식 Microsoft.VisualStudio.Services.Analytics.Model.Period 이며 날짜가 다른 기간(예: 주, 월 등)에서 완료되는지 확인할 수 있습니다.

<EnumType Name="Period" IsFlags="true">
  <Member Name="None" Value="0"/>
  <Member Name="Day" Value="1"/>
  <Member Name="WeekEndingOnSunday" Value="2"/>
  <Member Name="WeekEndingOnMonday" Value="4"/>
  <Member Name="WeekEndingOnTuesday" Value="8"/>
  <Member Name="WeekEndingOnWednesday" Value="16"/>
  <Member Name="WeekEndingOnThursday" Value="32"/>
  <Member Name="WeekEndingOnFriday" Value="64"/>
  <Member Name="WeekEndingOnSaturday" Value="128"/>
  <Member Name="Month" Value="256"/>
  <Member Name="Quarter" Value="512"/>
  <Member Name="Year" Value="1024"/>
  <Member Name="All" Value="2047"/>
</EnumType>

Microsoft.VisualStudio.Services.Analytics.Model.Period 플래그가 있는 열거형으로 정의되므로 OData has 연산자를 사용하고 마침표 리터럴의 전체 형식을 지정합니다.

IsLastDayOfPeriod has Microsoft.VisualStudio.Services.Analytics.Model.Period'Month'

예를 들어 다음 쿼리는 매월 마지막 날에 정의된 작업 항목 수를 반환합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemSnapshot?
  $apply=
    filter(IsLastDayOfPeriod has Microsoft.VisualStudio.Services.Analytics.Model.Period'Month')/
    groupby(
      (DateValue), 
      aggregate($count as Count)
    )

✔️ 태그로 필터링할 때 작업 항목에 컬렉션 속성 사용 Tags

함수와 TagNames 함께 contains 속성을 사용하여 작업이 특정 태그로 표시되었는지 확인할 수 있습니다. 그러나 이 방법은 특히 여러 태그를 동시에 검사 경우 쿼리 속도가 느려질 수 있습니다. 최상의 성능과 결과를 위해 탐색 속성을 대신 사용합니다 Tags .

예를 들어 다음 쿼리는 태그가 {tag}지정된 모든 작업 항목을 가져옵니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=Tags/any(t:t/TagName eq '{tag}')
  &$select=WorkItemId, Title, State

이 방법은 여러 태그를 필터링해야 하는 경우에도 효과적입니다. 예를 들어 다음 쿼리는 태그 {tag1}가 지정된 모든 작업 항목을 반환합니다.{tag2}

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=Tags/any(t:t/TagName eq {tag1} or t/TagName eq {tag2})
  &$select=WorkItemId, Title, State

이러한 필터를 "and" 연산자와 결합할 수도 있습니다. 예를 들어 다음 쿼리는 둘 다 {tag1}로 태그가 지정된 모든 작업 항목을 가져옵니다.{tag2}

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=Tags/any(t:t/TagName eq {tag1}) and Tags/any(t:t/TagName eq {tag2})
  &$select=WorkItemId, Title, State

✔️ 작업 항목의 모든 태그를 텍스트로 표시하려면 속성을 사용 TagNames 하세요.

이전 섹션에서 설명한 탐색 속성 Tags은 필터링에 적합합니다. 그러나 쿼리가 중첩된 컬렉션에서 태그를 반환하므로 이 작업을 수행하는 데 몇 가지 문제가 있습니다. 데이터 모델에는 태그 사용 시나리오를 TagNames 간소화하기 위해 추가한 기본 속성(Edm.String)도 포함되어 있습니다. 세미콜론 "; " 구분 기호와 결합된 모든 태그 목록을 포함하는 단일 텍스트 값입니다. 태그를 함께 표시하기만 하면 이 속성을 사용합니다. 앞에서 설명한 태그 필터와 결합할 수 있습니다.

예를 들어 다음 쿼리는 태그가 {tag}지정된 모든 작업 항목을 가져옵니다. 결합된 태그의 작업 항목 ID, 제목, 상태 및 텍스트 표현을 반환합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=Tags/any(t:t/TagName eq '{tag}')
  &$select=WorkItemId, Title, State, TagNames

Important

속성 TagNames 의 길이 제한은 1024자입니다. 여기에는 해당 제한에 맞는 태그 집합이 포함되어 있습니다. 작업 항목에 많은 태그가 있거나 태그가 매우 긴 TagNames 경우 전체 집합 Tag 을 포함하지 않고 탐색 속성을 대신 사용해야 합니다.

❌대/소문자를 구분하지 않는 비교를 수행하는 데 사용하지 tolower 마세요.toupper

다른 시스템에서 작업한 경우 대/소문자를 구분하지 않는 비교에 함수를 toupper 사용할 tolower 수 있습니다. Analytics를 사용하면 모든 문자열 비교가 기본적으로 대/소문자를 구분하지 않으므로 명시적으로 처리하기 위해 함수를 적용할 필요가 없습니다.

예를 들어 다음 쿼리는 "품질", "품질" 또는 이 단어의 다른 사례 조합으로 태그가 지정된 모든 작업 항목을 가져옵니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=Tags/any(t:t/TagName eq 'quality')
  &$select=WorkItemId, Title, State, TagNames

❌ 에 바인딩되지 않은 확장을 사용하지 마세요. $levels=max

OData에는 계층 구조의 모든 수준을 확장하는 기능이 있습니다. 예를 들어 작업 항목 추적에는 바인딩되지 않은 확장을 적용할 수 있는 일부 엔터티가 있습니다. 이 작업은 적은 양의 데이터가 있는 조직에서만 작동합니다. 더 큰 데이터 세트의 경우 크기가 잘 조정되지 않습니다. 다음과 같은 경우 전혀 사용하지 마세요.

  • 큰 데이터 세트로 작업하고 있습니다.
  • 위젯을 개발하고 있으며 위젯이 설치되는 위치를 제어할 수 없습니다.

✔️ 서버 기반 페이징 사용

단일 응답에서 전송할 수 없을 정도로 큰 집합을 요청하는 경우 Analytics는 페이징을 적용합니다. 응답에는 부분 집합 및 다음 부분 항목 집합을 검색할 수 있는 링크만 포함됩니다. 이 전략은 OData 사양 - OData 버전 4.0에 설명되어 있습니다. 1부: 프로토콜 - 서버 기반 페이징. 서비스가 페이징을 제어하도록 함으로써 각 엔터티가 최대한 효율적으로 설계되었기 때문에 skiptoken 최상의 성능을 얻을 수 있습니다.

다음 페이지에 대한 링크가 속성에 @odata.nextLink 포함됩니다.

{
  "@odata.context": "https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/$metadata#WorkItems(*)",
  "value": [
    ...
  ],
  "@odata.nextLink":"https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?$skiptoken=12345"}

참고 항목

대부분의 기존 OData 클라이언트는 서버 기반 페이징을 자동으로 처리할 수 있습니다. 예를 들어 이 전략은 Power BI, SQL Server Integration Services 및 Azure Data Factory 도구에서 이미 사용되고 있습니다.

❌ 클라이언트 기반 페이징을 구현하는 데 사용 $top 안 함 및 $skip 쿼리 옵션

다른 REST API를 사용하면 클라이언트 기반 페이징 $top$skip 쿼리 옵션을 구현했을 수 있습니다. 분석과 함께 사용하지 마세요. 이 접근 방식에는 몇 가지 문제가 있으며 성능도 그 중 하나입니다. 대신 이전 섹션에서 설명한 서버 기반 페이징 전략을 채택합니다.

✔️ 쿼리 옵션을 사용하여 $top 레코드 수 제한

쿼리 옵션은 $top .와 $skip함께 사용하는 경우에만 권장되지 않습니다. 보고 시나리오에서 레코드 하위 집합(예: 샘플)만 필요한 경우 쿼리 옵션을 사용하는 $top 것이 좋습니다. 또한 일부 기준에 따라 레코드의 순위를 지정해야 하는 경우 항상 상위 순위 레코드와 $orderby 안정적인 결과를 얻기 위해 함께 사용해야 $top 합니다.

✔️ 적은 수의 레코드를 반환하는 쿼리를 작성하는 것이 좋습니다.

적은 수의 레코드를 반환하는 쿼리를 작성하는 것이 가장 직관적인 지침입니다. 항상 관심 있는 데이터만 가져오는 것을 목표로 합니다. OData 쿼리 언어에서 사용할 수 있는 강력한 필터링 기능을 대부분 만들어서 달성할 수 있습니다.

✔️ 선택한 속성 수를 최소로 제한하는 것이 좋습니다.

일부 프로젝트 관리자는 사용자 지정 필드를 추가하여 프로세스를 크게 사용자 지정합니다. 사용자 지정이 많으면 넓은 엔터티에서 사용 가능한 모든 열을 가져올 때 성능 문제가 발생할 수 있습니다(예: WorkItems). 분석은 Columnstore 인덱스 기술을 기반으로 합니다. 즉, 데이터는 스토리지이고 쿼리 처리는 열 기반입니다. 따라서 쿼리에서 참조하는 속성이 많을수록 처리 비용이 더 많이 듭니다. 항상 쿼리의 속성 집합을 보고 시나리오에서 중요한 것으로 제한하는 것을 목표로 합니다.

✔️ 날짜 서로게이트 키 속성(DateSK 접미사)에 대한 필터링을 고려합니다.

날짜 필터를 정의하는 방법에는 여러 가지가 있습니다. 날짜 속성(예: CreatedDate탐색 대응) 또는 서로게이트 키 표현(예CreatedOnDateCreatedDate: )을 직접 필터링할 수 있습니다. 마지막 옵션은 최상의 성능을 생성하며 보고 요구 사항이 허용하는 경우 선호됩니다.

예를 들어 다음 쿼리는 2020년 초부터 만든 모든 작업 항목을 가져옵니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedDateSK ge 20200101

✔️ 서로게이트 키 열 필터링 고려

관련 개체의 값(예: 프로젝트 이름에서 작업 항목 필터링)에 대한 데이터를 필터링하려는 경우 항상 두 가지 선택 사항이 있습니다. 탐색 속성(예Project/ProjectName: )을 사용하거나 서로게이트 키를 앞에서 캡처하여 쿼리에서 직접 사용할 수 있습니다(예ProjectSK: ).

위젯을 빌드하는 경우 후자 옵션을 사용하는 것이 좋습니다. 키가 쿼리의 일부로 전달되면 터치해야 하는 엔터티 집합 수가 줄어들고 성능이 향상됩니다.

예를 들어 다음 쿼리는 탐색 속성이 아닌 Project/ProjectName 속성을 사용하여 ProjectSK 필터링합니다WorkItems.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=ProjectSK eq {projectSK}

❌또는 절의 $filter 속성을 사용하지 RevisionsParentChildren않도록 합니다.$expand

작업 항목은 전체 데이터 모델에서 가장 비용이 많이 드는 엔터티입니다. 관련 작업 항목에 액세스하는 데 사용할 수 있는 몇 가지 Parent탐색 속성이 ChildrenRevisions있습니다. 그러나 쿼리 내에서 사용할 때마다 성능이 저하됩니다. 이러한 속성 중 하나가 실제로 필요한지 항상 질문하고 디자인을 업데이트할 수 있습니다.

예를 들어 확장 대신 Parent더 많은 작업 항목을 가져오고 속성을 사용하여 ParentWorkItemId 전체 계층 구조 클라이언트 쪽을 재구성할 수 있습니다. 사례별로 이러한 최적화를 수행합니다.

✔️ 헤더에 기본 설정을 전달하는 VSTS.Analytics.MaxSize 것이 좋습니다.

쿼리를 실행할 때 쿼리가 반환하는 레코드 수를 알 수 없습니다. 집계를 사용하여 다른 쿼리를 보내거나 모든 다음 링크를 따라 전체 데이터 세트를 가져옵니다. 분석은 기본 설정을 준수 VSTS.Analytics.MaxSize 하므로 데이터 세트가 클라이언트가 허용할 수 있는 것보다 더 큰 인스턴스에서 빠르게 실패할 수 있습니다.

이 옵션은 데이터 내보내기 시나리오에서 유용합니다. 이를 사용하려면 HTTP 요청에 헤더를 추가하고 Prefer 음수가 아닌 값으로 설정 VSTS.Analytics.MaxSize 해야 합니다. 이 값은 VSTS.Analytics.MaxSize 허용할 수 있는 최대 레코드 수를 나타냅니다. 0으로 설정하면 기본값인 200K가 사용됩니다.

예를 들어 데이터 세트가 1000개 레코드와 작거나 같은 경우 다음 쿼리는 작업 항목을 반환합니다.

GET https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems HTTP/1.1
User-Agent: {application}
Prefer: VSTS.Analytics.MaxSize=1000
OData-MaxVersion: 4.0
Accept: application/json;odata.metadata=minimal
Host: analytics.dev.azure.com/{OrganizationName}

데이터 세트가 1000개의 레코드 제한을 초과하면 다음 오류와 함께 쿼리가 즉시 실패합니다.

쿼리 결과에는 1,296개의 행이 포함되며 최대 허용 크기인 1000을 초과합니다. 추가 필터를 적용하여 레코드 수를 줄이세요.

최대 페이지 크기를 설정하는 방법에 대한 자세한 내용은 ODataPreferenceHeader.MaxPageSize 속성을 참조 하세요.

쿼리 스타일 지침

✔️ 집계 메서드에서 가상 속성 사용 $count

일부 엔터티는 속성을 노출 Count 합니다. 데이터를 다른 스토리지로 내보낼 때 몇 가지 보고 시나리오를 더 쉽게 만듭니다. 그러나 OData 쿼리의 집계에서 이러한 열을 사용하면 안 됩니다. $count 대신 가상 속성을 사용합니다.

예를 들어 다음 쿼리는 총 작업 항목 수를 반환합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $apply=aggregate($count as Count)

❌ URL 세그먼트에서 가상 속성 사용 $count 방지

OData 표준을 사용하면 엔터티 집합(예_odata/v1.0/WorkItems/$count: 가상 속성)을 사용할 $count 수 있지만 모든 클라이언트가 응답을 올바르게 해석할 수 있는 것은 아닙니다. 따라서 집계를 대신 사용하는 것이 좋습니다.

예를 들어 다음 쿼리는 총 작업 항목 수를 반환합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $apply=aggregate($count as Count)

✔️ 매개 변수 별칭을 사용하여 쿼리의 휘발성 부분을 구분하는 것이 좋습니다.

매개 변수 별칭은 기본 쿼리 텍스트에서 매개 변수 값과 같은 휘발성 부분을 추출하는 세련된 솔루션을 제공합니다. 다음을 평가하는 식에서 사용할 수 있습니다.

  • 기본값
  • 복합 값
  • 기본 값 또는 복합 값의 컬렉션입니다.

자세한 내용은 OData 버전 4.0을 참조하세요. 2부: URL 규칙 - 5.1.1.13 매개 변수 별칭 매개 변수는 사용자가 제공한 값으로 인스턴스화할 수 있는 템플릿으로 쿼리 텍스트를 사용할 때 유용합니다.

예를 들어 다음 쿼리는 매개 변수를 사용하여 @createdDateSK 필터 식과 값을 구분합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=CreatedDateSK ge @createdDateSK
  &$select=WorkItemId, Title, State
  &@createdDateSK=20200101

❌ 단일 쿼리에서 혼합 $apply$filter 절을 사용하지 마십시오.

쿼리에 추가 filter 하려는 경우 두 가지 옵션이 있습니다. 절 또는 $apply=filter() 조합으로 $filter 수행할 수 있습니다. 이러한 각 옵션은 자체적으로 잘 작동하지만 함께 결합하면 예기치 않은 결과가 발생할 수 있습니다.

기대에도 불구하고 OData는 평가 순서를 명확하게 정의합니다. 또한 절에 $apply 우선 순위 $filter가 있습니다. 따라서 하나 또는 다른 항목을 선택해야 하지만 단일 쿼리에서 이러한 두 필터 옵션을 사용하지 않아야 합니다. 쿼리가 자동으로 생성되는 경우 중요합니다.

예를 들어 다음 쿼리는 먼저 작업 항목을 필터링하고 StoryPoint gt 5, 결과를 경로별로 집계하고, 마지막으로 결과를 StoryPoints gt 2필터링합니다. 이 평가 순서를 사용하면 쿼리는 항상 빈 집합을 반환합니다.

https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
  $filter=StoryPoints gt 2
  $apply=
    filter(StoryPoints gt 5)/
    groupby(
      (Area/AreaPath),
      aggregate(StoryPoints with sum as StoryPoints)
    )

✔️ OData 평가 순서와 일치하도록 쿼리를 구조화하는 것이 좋습니다.

단일 쿼리에서 혼합 $applyfilter 절을 사용하면 혼동이 발생할 수 있으므로 평가 순서와 일치하도록 쿼리 절을 구성하는 것이 좋습니다.

  1. $apply
  2. $filter
  3. $orderby
  4. $expand
  5. $select
  6. $skip
  7. $top

✔️ 메타데이터 주석에 설명된 OData 기능을 검토하는 것이 좋습니다.

Analytics에서 지원하는 OData 기능에 대해 잘 모르는 경우 메타데이터에서 주석을 조회할 수 있습니다. TC GitHub 리포지토리의 OASIS OData(Open Data Protocol) 기술 위원회는사용 가능한 주석 목록을 기본.

예를 들어 지원되는 필터 함수 목록은 엔터티 컨테이너의 주석에서 Org.OData.Capabilities.V1.FilterFunctions 사용할 수 있습니다.

<Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
  <Collection>
  <String>contains</String>
  <String>endswith</String>
  [...]
  </Collection>
</Annotation>

또 다른 유용한 주석은 Org.OData.Capabilities.V1.ExpandRestrictions절에서 $expand 사용할 수 없는 탐색 속성을 설명하는 주석입니다. 예를 들어 다음 주석은 엔터티 집합에서 WorkItems 확장할 수 없음을 설명 Revisions 합니다.

<EntitySet Name="WorkItems" EntityType="Microsoft.VisualStudio.Services.Analytics.Model.WorkItem">
  [...]
  <Annotation Term="Org.OData.Capabilities.V1.ExpandRestrictions">
    <Record>
      <PropertyValue Property="Expandable" Bool="true"/>
      <PropertyValue Property="NonExpandableProperties">
        <Collection>
          <NavigationPropertyPath>Revisions</NavigationPropertyPath>
        </Collection>
      </PropertyValue>
    </Record>
  </Annotation>
</EntitySet>