Wytyczne dotyczące zapytań usługi OData Analytics dla usługi Azure DevOps

Azure DevOps Services | Azure DevOps Server 2022 — Azure DevOps Server 2019

Deweloperzy rozszerzeń mogą skorzystać, postępując zgodnie z wytycznymi podanymi w tym artykule dotyczącymi projektowania wydajnych zapytań OData względem analizy dla usługi Azure DevOps. Przestrzeganie tych wytycznych pomaga zagwarantować, że zapytania mają dobrą wydajność w czasie wykonywania i zużyciu zasobów. Zapytania, które nie są zgodne z tymi wytycznymi, mogą spowodować niską wydajność z długim czasem oczekiwania raportu, zapytaniami przekraczającymi dozwolone użycie zasobów lub blokadami usług.

Uwaga

Usługa Analytics jest automatycznie włączona i obsługiwana w środowisku produkcyjnym dla wszystkich usług Azure DevOps Services. Integracja usługi Power BI i dostęp do źródła danych OData usługi Analytics są ogólnie dostępne. Zachęcamy do korzystania z niego i przekazywania opinii. Dostępne dane są zależne od wersji. Najnowsza obsługiwana wersja to v2.0, a najnowsza wersja zapoznawcza to v4.0-preview. Aby uzyskać więcej informacji, zobacz Przechowywanie wersji interfejsu API OData.

Uwaga

Usługa Analytics jest automatycznie instalowana i obsługiwana w środowisku produkcyjnym dla wszystkich nowych kolekcji projektów dla usługi Azure DevOps Server 2020 i nowszych wersji. Integracja usługi Power BI i dostęp do źródła danych OData usługi Analytics są ogólnie dostępne. Zachęcamy do korzystania z niego i przekazywania opinii. W przypadku uaktualnienia z usługi Azure DevOps Server 2019 możesz zainstalować usługę Analytics podczas uaktualniania.

Dostępne dane są zależne od wersji. Najnowsza obsługiwana wersja to v2.0, a najnowsza wersja zapoznawcza to v4.0-preview. Aby uzyskać więcej informacji, zobacz Przechowywanie wersji interfejsu API OData.

Uwaga

Usługa Analytics jest dostępna w wersji zapoznawczej dla usługi Azure DevOps Server 2019. Możesz włączyć lub zainstalować dla kolekcji projektów. Integracja usługi Power BI i dostęp do źródła danych OData usługi Analytics są dostępne w wersji zapoznawczej. Zachęcamy do korzystania z niego i przekazywania opinii.

Dostępne dane są zależne od wersji. Najnowsza obsługiwana wersja to v2.0, a najnowsza wersja zapoznawcza to v4.0-preview. Aby uzyskać więcej informacji, zobacz Przechowywanie wersji interfejsu API OData.

Te wytyczne są naszymi zaleceniami poprzedzonymi terminami DO, ROZWAŻ, UNIKAJ i NIE. Restrykcyjne reguły wymuszane przez usługę Analytics zawierają prefiks [BLOCKED]. Należy zrozumieć kompromisy między różnymi rozwiązaniami. W pewnych okolicznościach mogą istnieć wymagania dotyczące danych, które wymuszają naruszenie co najmniej jednego wytycznych. Takie przypadki powinny być rzadkie. Zalecamy, aby mieć jasny i przekonujący powód takich decyzji.

Napiwek

Przykłady przedstawione w tym dokumencie są oparte na adresie URL usługi Azure DevOps Services. Użyj podstawień dla wersji lokalnych.

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

Komunikaty o błędach i ostrzeżenia

✔️ Przegląd ostrzeżeń odpowiedzi OData

Każde wykonywane zapytanie jest sprawdzane względem zestawu wstępnie zdefiniowanych reguł. Naruszenia zwracają odpowiedź OData po @vsts.warnings. Przejrzyj te ostrzeżenia, ponieważ udostępniają bieżące i kontekstowe informacje na temat ulepszania zapytania.

{
  "@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."
  ],
  ...
}

✔️ Przejrzyj komunikaty o błędach OData

Zapytania naruszające regułę błędu OData powoduje niepowodzenie odpowiedzi z kodem stanu 400 (nieprawidłowe żądanie). Kojarzenie komunikatów nie jest wyświetlane we @vsts.warnings właściwości . Zamiast tego generują komunikat o błędzie we message właściwości w odpowiedzi JSON.

{
  "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."
  }
}

Ograniczenia

Czy

Rozważ następujące kwestie

Zablokowano

Uniknięcie

✔️ Czy ograniczyć zapytanie do projektów, do których masz dostęp

Jeśli zapytanie dotyczy danych z projektu, do którego nie masz dostępu, zapytanie zwraca komunikat "Odmowa dostępu do projektu". Aby upewnić się, że masz dostęp, upewnij się , że uprawnienie Wyświetl analizę ma ustawioną wartość Zezwalaj na wszystkie zapytania dotyczące projektów. Aby dowiedzieć się więcej, zobacz Uprawnienia wymagane do uzyskania dostępu do analizy.

Jeśli nie masz dostępu do projektu, zostanie wyświetlony następujący komunikat:

Wyniki zapytania obejmują dane w jednym lub kilku projektach, dla których nie masz dostępu. Dodaj co najmniej jeden filtr projektów, aby określić projekty, do których masz dostęp w jednostce "WorkItems". Jeśli używasz $expand lub właściwości nawigacji, filtr projektu jest wymagany dla tych jednostek.

Aby obejść ten problem, możesz jawnie dodać filtr projektu lub użyć punktu końcowego o zakresie projektu, jak wyjaśniono w dalszej części tego artykułu.

Na przykład następujące zapytanie pobiera elementy robocze, które należą do projektów o nazwach {projectSK1} i {projectSK2}.

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

✔️ CZY określić filtr projektu wewnątrz klauzuli $expand , jeśli rozszerzenie może zawierać dane w innych, potencjalnie niedostępnych projektach

Po rozwinięciu właściwości nawigacji istnieje prawdopodobieństwo, że odwołujesz się do danych z innych, niedostępnych projektów. Jeśli odwołujesz się do niedostępnych danych, zostanie wyświetlony ten sam komunikat o błędzie wymieniony wcześniej: "Wyniki zapytania zawierają dane w jednym lub kilku projektach...". Podobnie możesz rozwiązać ten problem, dodając jawne filtry projektu w celu kontrolowania rozszerzonych danych.

Można to zrobić w klauzuli regularnej $filter dla prostych właściwości nawigacji. Na przykład następujące zapytanie jawnie prosi o WorkItemLinks to, gdzie w tym samym projekcie istnieje zarówno link, jak i jego element docelowy.

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)

Zamiast tego możesz przenieść filtr, aby rozwinąć $filter opcję w klauzuli $expand . Jednak zmienia semantyczną kwerendę. Na przykład następujące zapytanie pobiera wszystkie linki z danego projektu i warunkowo rozszerza obiekt docelowy tylko wtedy, gdy istnieje w tym samym projekcie. Mimo że jest prawidłowe, takie podejście może spowodować zamieszanie, ponieważ może być trudne do określenia, czy właściwość nie jest rozwinięta, ponieważ jest lub null ponieważ została odfiltrowana. Użyj tego rozwiązania tylko wtedy, gdy naprawdę potrzebujesz tego konkretnego zachowania.

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)

Opcja rozwijania jest przydatna $filter w przypadku używania właściwości rozwiń kolekcję, takiej jak Children w WorkItems zestawie jednostek. Na przykład następujące zapytanie zwraca wszystkie elementy robocze z danego projektu wraz ze wszystkimi elementami podrzędnymi należącymi do tego samego projektu.

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)

Określ filtr, jeśli rozwiń jedną z następujących właściwości:

  • WorkItems zestaw jednostek: Parent, Children
  • WorkItemLinks zestaw jednostek: TargetWorkItem.

✔️ ROZWAŻ wykonywanie zapytań przy użyciu punktu końcowego o zakresie projektu

Jeśli interesuje Cię dane z jednego projektu, zalecamy użycie punktu końcowego OData o zakresie projektu (/{ProjectName}/_odata/v1.0). Pozwala uniknąć problemów opisanych w poprzednich dwóch sekcjach i niejawnie filtruje dane do jednego projektu, przywoływany zestaw jednostek i wszystkie rozwinięte właściwości nawigacji.

Z tym uproszczeniem zapytania z poprzedniej sekcji mogą zostać przepisane do następującego formularza. Nie tylko filtr w klauzuli expand zniknął, ale także nie ma potrzeby filtrowania w zestawie jednostek głównych.

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

Zapytanie dotyczące elementów roboczych podrzędnych jest również znacznie krótsze i prostsze.

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

To rozwiązanie można zastosować tylko wtedy, gdy fokus dotyczy danych z pojedynczego projektu. W przypadku raportowania między projektami należy użyć strategii filtrowania opisanych w poprzednich sekcjach.

✔️ Zaczekaj lub zatrzymaj operację, jeśli zapytanie przekroczy limity użycia

Jeśli wykonujesz wiele zapytań lub zapytania wymagają uruchomienia wielu zasobów, możesz przekroczyć limity usług i tymczasowo zablokować. Jeśli przekroczysz limity usługi, zatrzymaj operację jako prawdopodobieństwo, że następne wysyłane zapytanie zakończy się niepowodzeniem z tym samym komunikatem o błędzie.

Żądanie zostało zablokowane z powodu przekroczenia użycia zasobu "{resource}" w przestrzeni nazw "{namespace}".

Aby uzyskać więcej informacji na temat ograniczania szybkości, zobacz Limity szybkości. Aby dowiedzieć się, jak projektować wydajne zapytania OData, zapoznaj się z wytycznymi dotyczącymi wydajności w dalszej części tego artykułu.

✔️ Zaczekaj lub zatrzymaj operację, jeśli zapytanie zakończy się niepowodzeniem z przekroczeniem limitu czasu

Podobnie jak w przypadku przekroczenia limitów użycia, należy poczekać lub zatrzymać operację w przypadku przekroczenia limitu czasu zapytania. Może to sygnalizować przejściowy problem, więc możesz ponowić próbę raz, aby sprawdzić, czy problem zostanie rozwiązany. Jednak trwałe przekroczenia limitu czasu wskazują, że zapytanie jest prawdopodobnie zbyt kosztowne do uruchomienia. Dalsze ponawianie prób powoduje przekroczenie limitów użycia i zablokowanie.

TF400733: Żądanie zostało anulowane: Żądanie przekroczyło limit czasu żądania, spróbuj ponownie.

Limity czasu wskazują, że zapytanie wymaga optymalizacji. Aby dowiedzieć się, jak projektować wydajne zapytania OData, zobacz Wytyczne dotyczące wydajności w dalszej części tego artykułu.

❌ [ZABLOKOWANE] Nie używaj jednostek migawek w przypadku elementów innych niż agregacje

Zestawy jednostek migawek z sufiksem Snapshot są specjalne, ponieważ są modelowane jako codzienne migawki. Można ich użyć, aby uzyskać stan jednostek, ponieważ znajdowały się na końcu każdego dnia w przeszłości. Jeśli na przykład wykonano zapytanie i przefiltrowano WorkItemSnapshot do pojedynczego WorkItemIdelementu , otrzymasz jeden rekord dla każdego dnia od momentu utworzenia elementu roboczego. Ładowanie bezpośrednio wszystkich tych danych byłoby kosztowne i najprawdopodobniej przekroczy limity użycia i zostanie zablokowane. Jednak agregacje tych jednostek są dozwolone i zalecane. W rzeczywistości zestawy jednostek migawki zostały zaprojektowane z myślą o scenariuszach agregacji.

Na przykład następujące zapytanie pobiera liczbę elementów roboczych zgodnie z datą, aby zobaczyć, jak wzrosła w styczniu 2020 r.

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

Aby dowiedzieć się więcej na temat agregacji, zobacz Agregowanie danych.

✔️ Dołączanie DateSK lub DateValue kolumna w klauzuli podczas groupby agregowania tabel migawek

Ponieważ wszystkie jednostki migawek są modelowane jako codzienne tabele migawek, zawsze należy uwzględnić jedną z właściwości dnia (DateSK lub DateValue) w klauzuli grupowania. W przeciwnym razie wynik może pojawić się niepoprawnie zawyżony.

Jeśli na przykład pogrupowano WorkItemSnapshot tylko według AssignedTo właściwości i zagregowano ją z liczbą, pomnożą wszystkie liczby elementów roboczych przypisanych do osób przez liczbę dni, w których każde przypisanie było aktywne. Chociaż może wystąpić sytuacja, w której jest to pożądany wynik, takie przypadki są rzadkie.

❌ [ZABLOKOWANE] Nie używaj kluczy jednostek w ścieżkach zasobów na potrzeby adresowania jednostek

Składnia OData umożliwia uzyskiwanie dostępu do określonej jednostki przez uwzględnienie kluczy bezpośrednio w segmentach adresów URL. Aby uzyskać więcej informacji, zobacz OData w wersji 4.0. Część 2. Konwencje adresów URL — 4.3 adresowanie jednostek. Mimo że usługa OData zezwala na takie adresowanie, usługa Analytics blokuje je. Dołączenie do zapytania powoduje następujący błąd.

Kwerenda określona w identyfikatorze URI jest nieprawidłowa. Analiza nie obsługuje nawigacji kluczy ani właściwości, takich jak WorkItems(Id) ani WorkItem(Id)/AssignedTo. Jeśli wystąpi ten błąd w usłudze Power BI, napisz ponownie zapytanie, aby uniknąć nieprawidłowego składania, które powoduje problem N+1.

Ponieważ komunikaty o błędach wskazują, niektóre narzędzia klienckie mogą nadużywać bezpośredniego adresowania jednostek. Zamiast ładować wszystkie dane w jednym żądaniu, klienci mogą zdecydować się na niezależne wykonywanie zapytań dotyczących każdej jednostki. Ta praktyka jest zniechęcana, ponieważ może to spowodować dużą liczbę żądań. Zamiast tego zalecamy używanie jawnego adresowania jednostek zgodnie z wyjaśnieniem w poniższej sekcji.

✔️ Jawne rozwiązywanie problemów z jednostkami za pomocą klauzul filtru

Jeśli chcesz pobrać dane dla pojedynczej jednostki, należy użyć tego samego podejścia co w przypadku kolekcji jednostek i jawnie zdefiniować filtry w klauzuli $filter .

Na przykład następujące zapytanie pobiera jeden element roboczy według jego identyfikatora.

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

Jeśli nie masz pewności, które właściwości należy uwzględnić w takim filtrze, możesz wyszukać je w metadanych. Zobacz Konstruowanie zapytań OData dla analizy, składników adresu URL w celu wykonywania zapytań dotyczących metadanych. Właściwości znajdują się w Key elemecie EntityType. Na przykład WorkItemId kolumny kluczy Revision dla jednostki są kolumnami kluczowymi WorkItemRevision .

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

❌ [ZABLOKOWANE] Nie rozszerzaj RevisionsWorkItem jednostki

Model danych analizy nie zezwala na pewne typy rozszerzeń. Jedną z nich, co może być zaskakujące dla niektórych, jest Revisions właściwość kolekcji w jednostce WorkItem . Jeśli spróbujesz rozwinąć tę właściwość, zostanie wyświetlony następujący komunikat o błędzie.

Kwerenda określona w identyfikatorze URI jest nieprawidłowa. Nie można użyć właściwości "Revisions" w opcji zapytania $expand.

To ograniczenie zostało wprowadzone, aby zachęcić wszystkich do korzystania z zalecanego rozwiązania, które pobiera poprawki zgodnie z WorkItemRevisions wyjaśnieniem w poniższej sekcji.

✔️ Czy użyć WorkItemRevisions zestawu jednostek, aby załadować wszystkie poprawki dla danego elementu roboczego

Użyj WorkItemRevisions za każdym razem, gdy chcesz pobrać pełną historię elementu roboczego lub kolekcji elementów roboczych.

Na przykład następujące zapytanie zwraca wszystkie poprawki elementu roboczego z identyfikatorem {id} .

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

Jeśli zależy Ci na pełnej historii wszystkich elementów roboczych spełniających określone kryteria, należy wyrazić ją przy użyciu filtru we WorkItem właściwości nawigacji. Na przykład następujące zapytanie pobiera wszystkie poprawki wszystkich aktualnie aktywnych elementów roboczych.

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

❌ [ZABLOKOWANE] Nie grupuj na odrębnych kolumnach

Aby zmniejszyć liczbę rekordów, należy użyć operacji grupowania. Użycie odrębnych kolumn w klauzuli groupby wskazuje problem, a zapytanie natychmiast kończy się niepowodzeniem. Jeśli przypadkowo wystąpi taka sytuacja, zostanie wyświetlony następujący komunikat o błędzie.

Co najmniej jedna kolumna określona w klauzuli groupby tego zapytania nie jest zalecana.

Aby rozwiązać ten problem, usuń odrębną kolumnę z klauzuli groupby .

❌ [ZABLOKOWANE] Nie używaj countdistinct agregacji

Analiza nie obsługuje funkcji, mimo że funkcja OData nie jest wykonywana countdistinct . Chociaż planujemy dodać obsługę w przyszłości, obecnie nie jest ona dostępna. Zapytanie zawierające tę funkcję zwraca następujący komunikat o błędzie.

Zapytania, które stosują liczbę odrębną z agregacją, nie są obsługiwane.

❌ UNIKAJ agregacji, które mogą powodować przepełnienie arytmetyczne

W rzadkich przypadkach zapytanie agregacji może napotkać problemy z przepełnieniem arytmetycznym. Na przykład może się zdarzyć, gdy sumujesz niektóre właściwości liczbowe, które nie są przeznaczone do sumowania, na przykład StackRank w jednostkach elementu roboczego. Ponieważ rozszerzenie OData dla standardu agregacji danych nie zapewnia sposobu rzutowania właściwości na inny typ, jedynym sposobem rozwiązania tego problemu jest usunięcie problematycznej właściwości z agregacji.

✔️ Użyj punktu końcowego wsadowego dla długich zapytań

Mogą wystąpić problemy z długimi zapytaniami. Szczególnie problemy mogą wystąpić, gdy:

  • Wykonasz zapytanie dotyczące projektu z wieloma polami niestandardowymi.
  • Zapytanie jest konstruowane programowo.

Bieżący limit wysyłanych HTTP GET zapytań OData wynosi 3000 znaków. Jeśli go przekroczysz, otrzymasz odpowiedź "404 Nie znaleziono".

HTTP/1.1 404 Not Found
Content-Length: 0

Aby rozwiązać ten problem, użyj punktu końcowego usługi OData wsadowej zgodnie ze specyfikacją OData w wersji 4.0. Część 1: Protokół — 11.7 Żądania wsadowe. Funkcja usługi Batch została zaprojektowana głównie w celu grupowania wielu operacji w jednym HTTP ładunku żądania, ale można jej również użyć jako obejścia ograniczenia długości zapytania. Wysyłając HTTP POST żądanie, możesz przekazać zapytanie o dowolną długość, a usługa je poprawnie interpretuje.

❌ [ZABLOKOWANE] Nie używaj punktu końcowego wsadowego do wysyłania wielu zapytań

Ograniczamy użycie punktu końcowego wsadowego do obsługi partii wielu żądań. Pojedyncze żądanie nadal może mieć tylko jedno zapytanie. Jeśli spróbujesz wysłać partię kilku zapytań, operacja zakończy się niepowodzeniem z następującym komunikatem o błędzie. Jedynym rozwiązaniem jest podzielenie zapytań na wiele żądań.

Analiza nie obsługuje przetwarzania wielu operacji, które zawiera bieżący komunikat wsadowy. Analiza używa usługi OData batch w celu obsługi żądań POST, ale wymaga ograniczenia operacji do pojedynczego żądania.

❌ [ZABLOKOWANE] Nie używaj zapytań, które powodują więcej niż 800 kolumn

Ograniczamy zapytania, które powodują więcej niż 800 kolumn. Jeśli nie jesteś wystarczająco selektywny, w których kolumny zwraca zapytanie, może zostać wyświetlony następujący komunikat o błędzie.

VS403670: określone zapytanie zwraca kolumny "N", które są wyższe niż dozwolony limit 800 kolumn. Aby ograniczyć liczbę kolumn, użyj jawnych $select (w tym w $expand).

Dodaj klauzulę $select do zapytania i w celu $expand operacji w zapytaniu, aby uniknąć przekroczenia tego limitu.

❌ UNIKAJ tworzenia długich zapytań

Zalecamy ocenę podejścia za każdym razem, gdy utworzysz długie zapytanie. Istnieje wiele scenariuszy, które wymagają długiego zapytania (na przykład złożonych filtrów lub długiej listy właściwości), zazwyczaj zapewniają one wczesny wskaźnik nieoptymalnego projektu.

Jeśli zapytanie zawiera wiele kluczy jednostki w zapytaniu (na przykład WorkItemId eq {id 1} or WorkItemId eq {id 2} or ...), prawdopodobnie możesz go ponownie napisać. Zamiast przekazywać identyfikatory, spróbuj zdefiniować inne kryteria, które wybierają ten sam zestaw jednostek. Czasami może być konieczne zmodyfikowanie procesu (na przykład dodanie nowego pola lub tagu), ale zazwyczaj warto. Zapytania korzystające z bardziej abstrakcyjnych filtrów są łatwiejsze do utrzymania i mają większy potencjał do lepszego działania.

Inny scenariusz, który ma tendencję do generowania długich zapytań, występuje w przypadku uwzględnienia wielu pojedynczych dat (na przykład DateSK eq {dateSK 1} or DateSK eq {dateSK 2} or ...). Poszukaj innego wzorca, którego można użyć do utworzenia bardziej abstrakcyjnego filtru. Na przykład następujące zapytanie zwraca wszystkie elementy robocze, które zostały utworzone w poniedziałek.

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

✔️ CZY określać strefę czasową podczas filtrowania kolumn dat

Strefa czasowa (Edm.DateTimeOffset) uwidacznia wszystkie informacje o dacie i godzinie z przesunięciem zgodnym z ustawieniami strefy czasowej organizacji. Te dane są dokładne i proste do zinterpretowania w tym samym czasie. Kolejną nieobjętą konsekwencją jest to, że wszystkie filtry muszą również przekazać informacje o strefie czasowej. Jeśli pominiesz go, zostanie wyświetlony następujący komunikat o błędzie.

Kwerenda określona w identyfikatorze URI jest nieprawidłowa. Nie określono przesunięcia daty/godziny. Użyj jednego z tych formatów RRRR-MM-ddZ, aby określić wszystko od północy lub rrrr-MM-ddThh:mm-hh:mm (standardowa reprezentacja dat i godzin ISO 8601) w celu określenia przesunięcia.

Aby rozwiązać ten problem, dodaj informacje o strefie czasowej. Na przykład przy założeniu, że organizacja jest skonfigurowana do wyświetlania danych w strefie czasowej pacyficznej (STANY ZJEDNOCZONE i Kanada) (UTC-08:00), następujące zapytanie pobiera wszystkie elementy robocze utworzone od początku 2020 roku.

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

To samo rozwiązanie działa w przypadku stref czasowych z dodatnimi przesunięciami, jednak znak plus (+) ma specjalne znaczenie w identyfikatorze URI i musisz go poprawnie obsłużyć. Jeśli określisz 2020-01-01T00:00:00+08:00 (z znakiem + ) jako punkt początkowy, zostanie wyświetlony następujący błąd.

Kwerenda określona w identyfikatorze URI jest nieprawidłowa. Błąd składniowy na pozycji 31 w obszarze "CreatedDate ge 2020-01-01T00000 08:00".

Aby rozwiązać ten problem, zastąp + znak jego zakodowaną wersją , %2B. Na przykład przy założeniu, że organizacja jest skonfigurowana do wyświetlania danych w "(UTC+08:00) Pekin, Chongqing, Hong Kong, Urumqi" strefa czasowa, następujące zapytanie zwraca wszystkie elementy robocze utworzone od początku 2020 roku.

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

Alternatywną metodą jest użycie właściwości klucza zastępczego daty, ponieważ nie przechowują informacji o strefie czasowej. Na przykład następujące zapytanie zwraca wszystkie elementy robocze utworzone od początku 2020 r., niezależnie od ustawień organizacji.

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

Wytyczne dotyczące wydajności

Czy

Nie rówieś

Rozważ następujące kwestie

Uniknięcie

✔️ DO measure the effect of implement a performance wytyczne

Podobnie jak w przypadku żadnych zaleceń dotyczących wydajności, nie należy ich ślepo implementować. Zamiast tego należy zawsze przechwytywać punkt odniesienia i mierzyć efekt włączonych zmian. Wszystkie wytyczne zostały utworzone na podstawie interakcji z klientami analizy, którzy mieli określone wymagania i wyzwania. Te zalecenia zostały uznane za ogólne i potencjalnie przydatne dla każdego, kto projektuje podobne zapytania. Jednak w rzadkich przypadkach przestrzeganie wytycznych nie może mieć wpływu ani nawet negatywnego wpływu na wydajność. Musisz zmierzyć różnicę, aby ją zauważyć. Jeśli tak się stanie, przekaż opinię w portalu Społeczności deweloperów.

Istnieje wiele opcji mierzenia wydajności. Najprostszym z nich jest uruchomienie dwóch wersji tego samego zapytania bezpośrednio w przeglądarce. Obserwuj czas potrzebny w narzędziach deweloperskich. Na przykład można użyć panelu sieci w narzędziu Microsoft Edge F12 Developer Tools. Inną opcją jest przechwycenie tych informacji przy użyciu narzędzia Fiddler Web Debugger Tool.

Niezależnie od podejścia, uruchom oba zapytania wiele razy. Na przykład uruchom zapytania 30 razy, aby mieć wystarczająco duży zestaw próbek. Następnie ustalizuj charakterystykę wydajności. Analiza jest zgodna z architekturą wielodostępną. Dlatego inne operacje występujące w tym samym czasie mogą mieć wpływ na czas trwania zapytań.

✔️ Czy używać rozszerzeń agregacji

Zdecydowanie najlepszą rzeczą, jaką można zrobić, aby zwiększyć wydajność zapytań, jest użycie rozszerzenia agregacji — rozszerzenie OData dla agregacji danych. W przypadku rozszerzenia agregacji poproś usługę o podsumowanie po stronie serwera danych i zwrócenie mniejszej odpowiedzi niż to, co można pobrać, stosując tę samą funkcję po stronie klienta. Na koniec analiza jest zoptymalizowana pod kątem tego typu zapytań, więc korzystaj z niej.

Aby dowiedzieć się więcej, zobacz Agregowanie danych.

✔️ DO określ kolumny w klauzuli $select

Określ kolumny, o których mowa w klauzuli $select . Analiza jest oparta na technologii index magazynu kolumn. Oznacza to, że dane są zarówno magazynem, jak i przetwarzanie zapytań jest oparte na kolumnach. Zmniejszając zestaw właściwości, odwołujesz się do $select klauzuli , możesz zmniejszyć liczbę kolumn, które muszą zostać zeskanowane i poprawić ogólną wydajność zapytania.

Na przykład następujące zapytanie określa kolumny elementów roboczych.

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

Uwaga

Usługa Azure DevOps obsługuje dostosowywanie procesów. Niektórzy administratorzy używają tej funkcji i tworzą setki pól niestandardowych. Jeśli pominiesz klauzulę $select , zapytanie zwróci wszystkie pola, w tym pola niestandardowe.

✔️ CZY określić kolumny w $select opcji rozwijania wewnątrz klauzuli $expand

Podobnie jak $select w przypadku wytycznych dotyczących klauzuli, określ właściwości w opcji rozwijania w $select klauzuli $expand . Łatwo zapomnieć, ale jeśli pominięto ją, odpowiedź zawiera wszystkie właściwości obiektu rozwiniętego.

Na przykład następujące zapytanie określa kolumny zarówno dla elementu roboczego, jak i jego elementu nadrzędnego.

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

✔️ Czy zdefiniować filtr podczas RevisedDateSK wykonywania zapytań dotyczących historycznych danych elementów roboczych (WorkItemRevisions lub WorkItemSnapshot zestawów jednostek)

Podczas wykonywania zapytań dotyczących danych historycznych prawdopodobieństwo, że interesuje Cię najnowszy okres (na przykład 30 dni, 90 dni). Ze względu na sposób implementowania jednostek elementów roboczych istnieje wygodny sposób pisania takich zapytań w celu uzyskania wysokiej wydajności. Za każdym razem, gdy aktualizujesz element roboczy, tworzy nową poprawkę i rejestruje tę akcję w System.RevisedDate polu, co sprawia, że idealnie nadaje się do filtrów historii.

W obszarze Analiza zmieniona data jest wyświetlana we właściwościach RevisedDate (Edm.DateTimeOffset) i RevisedDateSK (Edm.Int32). Aby uzyskać najlepszą wydajność, użyj tej drugiej. Jest to klucz zastępczy daty i reprezentuje datę utworzenia poprawki lub null dla aktywnych, niekompletnych poprawek. Jeśli chcesz, aby wszystkie daty od włącznie {startDate} , dodaj następujący filtr do zapytania.

RevisedDateSK eq null or RevisedDateSK gt {startDateSK}

Na przykład następujące zapytanie zwraca liczbę elementów roboczych dla każdego dnia od początku 2020 roku. Zwróć uwagę, że oprócz oczywistego filtru w DateSK kolumnie znajduje się drugi filtr dla elementu RevisedDateSK. Chociaż może się wydawać nadmiarowe, aparat zapytań pomaga odfiltrować poprawki, które nie są w zakresie i znacznie poprawia wydajność zapytań.

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)
    )

Uwaga

Wymyśliliśmy to zalecenie podczas pracy nad widżetami Burndown. Początkowo zdefiniowaliśmy tylko filtry, DateSK ale nie mogliśmy uzyskać tego zapytania w celu skalowania dobrze dla organizacji z dużymi zestawami danych. Podczas profilowania zapytań zauważyliśmy, że DateSK nie filtruje poprawek. Dopiero po dodaniu filtru w RevisedDateSK systemie byliśmy w stanie uzyskać doskonałą wydajność na dużą skalę.
~ Zespół produktu

✔️ Używaj cotygodniowych lub miesięcznych migawek dla zapytań trendów obejmujących długi okres

Domyślnie wszystkie tabele migawek są modelowane jako codzienne tabele faktów migawek. Jeśli wykonasz zapytanie o zakres czasu, otrzyma wartość dla każdego dnia. Zakresy czasu długiego powodują dużą liczbę rekordów. Jeśli nie potrzebujesz takiej wysokiej precyzji, możesz użyć cotygodniowych lub nawet miesięcznych migawek.

Możesz to zrobić za pomocą innych wyrażeń filtru, aby usunąć dni, które nie zakończą danego tygodnia lub miesiąca. IsLastDayOfPeriod Użyj właściwości , która została dodana do analizy, mając na uwadze ten scenariusz. Ta właściwość jest typu Microsoft.VisualStudio.Services.Analytics.Model.Period i może określić, czy dzień kończy się w różnych okresach (na przykład tygodni, miesięcy itd.).

<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>

Ponieważ Microsoft.VisualStudio.Services.Analytics.Model.Period jest definiowana jako wyliczenie z flagami, użyj operatora OData has i określ pełny typ literałów okresu.

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

Na przykład następujące zapytanie zwraca liczbę elementów roboczych zdefiniowanych w ostatnim dniu każdego miesiąca.

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)
    )

✔️ Czy używać Tags właściwości kolekcji w elementach roboczych podczas filtrowania według tagów

Możesz użyć TagNames właściwości z contains funkcją , aby określić, czy praca została oznaczona określonym tagiem. Takie podejście może jednak spowodować spowolnienie zapytań, zwłaszcza podczas sprawdzania wielu tagów w tym samym czasie. Aby uzyskać najlepszą Tags wydajność i wyniki, użyj właściwości nawigacji.

Na przykład następujące zapytanie pobiera wszystkie elementy robocze oznaczone tagiem {tag}.

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

Takie podejście działa również świetnie, gdy trzeba filtrować wiele tagów. Na przykład następujące zapytanie zwraca wszystkie elementy robocze oznaczone tagiem {tag1}lub{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

Można również połączyć te filtry z operatorem "and". Na przykład następujące zapytanie pobiera wszystkie elementy robocze, które zostały oznaczone tagiem i {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 Użyj właściwości DO, jeśli chcesz wyświetlić wszystkie tagi w elemencie roboczym jako tekst

Właściwość Tagsnawigacji opisana w poprzedniej sekcji doskonale nadaje się do filtrowania. Jednak praca z nimi stanowi pewne wyzwania, ponieważ zapytanie zwraca tagi w zagnieżdżonej kolekcji. Model danych zawiera również właściwość pierwotną TagNames (Edm.String), którą dodaliśmy w celu uproszczenia scenariuszy użycia tagów. Jest to pojedyncza wartość tekstowa zawierająca listę wszystkich tagów połączonych z separatorem średnika "; ". Użyj tej właściwości, gdy wszystko, o co chodzi, wyświetla tagi razem. Można połączyć je z opisanymi wcześniej filtrami tagów.

Na przykład następujące zapytanie pobiera wszystkie elementy robocze oznaczone tagiem {tag}. Zwraca identyfikator elementu roboczego, tytuł, stan i tekstową reprezentację połączonych tagów.

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

Ważne

Właściwość TagNames ma limit długości 1024 znaków. Zawiera zestaw tagów pasujących do tego limitu. Jeśli element roboczy ma wiele tagów lub tagi są bardzo długie, TagNames nie należy używać pełnej właściwości zestawu i Tag nawigacji.

❌ Nie używaj tolower funkcji i toupper do porównywania bez uwzględniania wielkości liter

Jeśli pracujesz z innymi systemami, możesz oczekiwać użycia tolower funkcji lub toupper w przypadku porównania bez uwzględniania wielkości liter. W przypadku analizy wszystkie porównania ciągów są domyślnie niewrażliwe na wielkość liter, więc nie trzeba stosować żadnych funkcji, aby jawnie je obsłużyć.

Na przykład następujące zapytanie pobiera wszystkie elementy robocze oznaczone etykietą "QUALITY", "quality" lub dowolną inną kombinacją tego słowa.

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

❌ Nie używaj rozszerzenia bez ruchu z $levels=max

OData ma możliwość rozszerzenia wszystkich poziomów struktury hierarchicznej. Na przykład śledzenie elementów roboczych zawiera pewne jednostki, w których można zastosować rozszerzenie bez ruchu. Ta operacja działa tylko w przypadku organizacji z niewielką ilością danych. Nie jest ona skalowana w przypadku większych zestawów danych. Nie używaj go w ogóle, jeśli:

  • Pracujesz z dużymi zestawami danych.
  • Tworzysz widżet i nie masz kontroli nad miejscem instalacji widżetu.

✔️ Czy używać stronicowania opartego na serwerze

Jeśli poprosisz o zestaw, który jest zbyt duży, aby został wysłany w jednej odpowiedzi, analiza stosuje stronicowanie. Odpowiedź zawiera tylko zestaw częściowy i link umożliwiający pobranie kolejnego częściowego zestawu elementów. Ta strategia jest opisana w specyfikacji OData — OData w wersji 4.0. Część 1: Protokół — stronicowanie oparte na serwerze. Pozwalając usłudze kontrolować stronicowanie, uzyskujesz najlepszą wydajność, ponieważ skiptoken została starannie zaprojektowana dla każdej jednostki, aby była tak wydajna, jak to możliwe.

Link do następnej strony znajduje się we @odata.nextLink właściwości .

{
  "@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"}

Uwaga

Większość istniejących klientów OData może automatycznie obsługiwać stronicowanie oparte na serwerze. Na przykład ta strategia jest już używana przez następujące narzędzia: Power BI, SQL Server Integration Services i Azure Data Factory.

❌ Nie używaj $top opcji zapytania i $skip do implementowania stronicowania opartego na kliencie

W przypadku innych interfejsów API REST można zaimplementować stronicowanie oparte na klientach z opcjami $top zapytań i $skip . Nie używaj ich z usługą Analytics. Istnieje kilka problemów z tym podejściem, a wydajność jest jednym z nich. Zamiast tego zastosuj strategię stronicowania opartą na serwerze opisaną w poprzedniej sekcji.

✔️ $top Użyj opcji kwerendy, aby ograniczyć liczbę rekordów

Opcja $top kwerendy jest odradzana tylko w przypadku używania razem z $skip. Jeśli w scenariuszu raportowania potrzebujesz tylko podzestawu rekordów (na przykład przykładu), warto użyć $top opcji zapytania. Ponadto, jeśli musisz sklasyfikować rekordy zgodnie z pewnymi kryteriami, zawsze należy użyć $top w połączeniu z $orderby , aby uzyskać stabilny wynik z rekordami o najwyższej klasyfikacji.

✔️ ROZWAŻ napisanie zapytania w celu zwrócenia niewielkiej liczby rekordów

Pisanie zapytania zwracającego niewielką liczbę rekordów jest najbardziej intuicyjną wskazówką. Zawsze staraj się pobierać tylko dane, o których naprawdę ci zależy. Można to osiągnąć, udostępniając większość zaawansowanych funkcji filtrowania w języku zapytań OData.

✔️ ROZWAŻ ograniczenie liczby wybranych właściwości do minimum

Niektórzy administratorzy projektów w dużym stopniu dostosowują swoje procesy, dodając pola niestandardowe. Duże dostosowanie może prowadzić do problemów z wydajnością podczas pobierania wszystkich dostępnych kolumn w jednostkach szerokich (na przykład WorkItems). Analiza jest oparta na technologii index magazynu kolumn. Oznacza to, że dane są zarówno magazynem, jak i przetwarzanie zapytań jest oparte na kolumnach. Dlatego tym więcej właściwości, do których odwołuje się zapytanie, tym droższe jest przetwarzanie. Zawsze staraj się ograniczyć zestaw właściwości w zapytaniach do tego, co naprawdę interesuje Cię w scenariuszu raportowania.

✔️ ROZWAŻ filtrowanie we właściwościach klucza zastępczego daty (DateSK sufiks)

Istnieje wiele sposobów definiowania filtru daty. Właściwość date można filtrować bezpośrednio (na przykład CreatedDate), jej odpowiednik nawigacji (na przykład ) lub jego zastępczą reprezentację klucza (na przykład CreatedOnDateCreatedDate). Ostatnia opcja daje najlepszą wydajność i jest preferowana, gdy zezwalają na to wymagania raportowania.

Na przykład następujące zapytanie pobiera wszystkie elementy robocze utworzone od początku 2020 roku.

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

✔️ ROZWAŻ filtrowanie kolumn kluczy zastępczych

Jeśli chcesz filtrować dane dotyczące wartości powiązanego obiektu (na przykład filtrowanie elementu roboczego w nazwie projektu), zawsze masz dwie opcje. Możesz użyć właściwości nawigacji (na przykład Project/ProjectName) lub przechwycić klucz zastępczy z góry i użyć go bezpośrednio w zapytaniu (na przykład ProjectSK).

Jeśli tworzysz widżet, zalecamy użycie tej drugiej opcji. Po przekazaniu klucza w ramach zapytania liczba zestawów jednostek, które muszą być dotykane, zostanie zmniejszona, a wydajność się poprawia.

Na przykład następujące filtry zapytania WorkItems używają ProjectSK właściwości, a nie Project/ProjectName właściwości nawigacji.

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

❌UNIKAJ używania Parentwłaściwości , lub ChildrenRevisions w $filter klauzulach or $expand

Elementy robocze to najdroższe jednostki w całym modelu danych. Mają one kilka właściwości nawigacji, których można użyć do uzyskiwania dostępu do powiązanych elementów roboczych: Parent, , ChildrenRevisions. Za każdym razem, gdy używasz ich w zapytaniu, spodziewaj się jednak spadku wydajności. Zawsze pytaj, czy naprawdę potrzebujesz jednej z tych właściwości i potencjalnie zaktualizuj projekt.

Na przykład zamiast rozszerzać Parentelement , można pobrać więcej elementów roboczych i użyć ParentWorkItemId właściwości do odtworzenia pełnej hierarchii po stronie klienta. Przeprowadzenie takiej optymalizacji na podstawie wielkości liter.

✔️ ROZWAŻ przekazanie VSTS.Analytics.MaxSize preferencji w nagłówku

Podczas wykonywania zapytania nie wiadomo, ile rekordów zwraca zapytanie. Wyślij kolejne zapytanie z agregacjami lub postępuj zgodnie ze wszystkimi kolejnymi linkami i pobierz cały zestaw danych. Analiza uwzględnia VSTS.Analytics.MaxSize preferencje, co pozwala szybko zakończyć się niepowodzeniem w tych wystąpieniach, że zestaw danych jest większy niż to, co klient może zaakceptować.

Ta opcja jest przydatna w scenariuszach eksportowania danych. Aby go użyć, musisz dodać Prefer nagłówek do żądania HTTP i ustawić VSTS.Analytics.MaxSize wartość nieujemną. Wartość VSTS.Analytics.MaxSize reprezentuje maksymalną liczbę rekordów, które można zaakceptować. Jeśli ustawisz ją na zero, zostanie użyta wartość domyślna 200 K.

Na przykład następujące zapytanie zwraca elementy robocze, jeśli zestaw danych jest mniejszy lub równy 1000 rekordów.

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}

Jeśli zestaw danych przekroczy limit 1000 rekordów, zapytanie natychmiast zakończy się niepowodzeniem z powodu następującego błędu.

Wynik zapytania zawiera 1296 wierszy i przekracza maksymalny dozwolony rozmiar 1000. Zmniejsz liczbę rekordów, stosując dodatkowe filtry

Aby uzyskać informacje na temat ustawiania maksymalnego rozmiaru strony, zobacz właściwość ODataPreferenceHeader.MaxPageSize.

Wskazówki dotyczące stylu zapytania

✔️ Do użyj $count właściwości wirtualnej w metodach agregacji

Niektóre jednostki uwidaczniają Count właściwość. Ułatwiają one niektóre scenariusze raportowania, gdy dane zostaną wyeksportowane do innego magazynu. Nie należy jednak używać tych kolumn w agregacjach w zapytaniach OData. $count Zamiast tego użyj właściwości wirtualnej.

Na przykład następujące zapytanie zwraca łączną liczbę elementów roboczych.

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

❌ UNIKAJ używania $count właściwości wirtualnej w segmencie adresu URL

Mimo że standard OData umożliwia używanie $count właściwości wirtualnej dla zestawów jednostek (na przykład _odata/v1.0/WorkItems/$count), nie wszyscy klienci mogą poprawnie interpretować odpowiedź. Dlatego zaleca się użycie agregacji.

Na przykład następujące zapytanie zwraca łączną liczbę elementów roboczych.

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

✔️ ROZWAŻ użycie aliasów parametrów, aby oddzielić nietrwałe części zapytania

Aliasy parametrów zapewniają eleganckie rozwiązanie do wyodrębniania nietrwałych części, takich jak wartości parametrów z głównego tekstu zapytania. Można ich używać w wyrażeniach, które oceniają:

  • Wartość pierwotna
  • Wartość złożona
  • Kolekcja wartości pierwotnych lub złożonych.

Aby uzyskać więcej informacji, zobacz OData w wersji 4.0. Część 2. Konwencje adresów URL — aliasy parametrów 5.1.1.13. Parametry są przydatne, gdy tekst zapytania jest używany jako szablon, który można utworzyć wystąpienia przy użyciu wartości dostarczonych przez użytkownika.

Na przykład następujące zapytanie używa @createdDateSK parametru , aby oddzielić wartość od wyrażenia filtru.

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

❌ UNIKAJ mieszania $apply i $filter klauzul w jednym zapytaniu

Jeśli chcesz dodać filter zapytanie, masz dwie opcje. Można to zrobić za pomocą klauzuli $filter lub kombinacji $apply=filter() . Każda z tych opcji działa świetnie samodzielnie, ale połączenie ich razem może prowadzić do nieoczekiwanych wyników.

Pomimo oczekiwań, które można mieć, OData jasno definiuje kolejność oceny. Ponadto klauzula $apply ma priorytet nad $filter. Z tego powodu należy wybrać jedną lub drugą, ale uniknąć tych dwóch opcji filtrowania w jednym zapytaniu. Ważne jest, aby zapytania zostały wygenerowane automatycznie.

Na przykład następujące zapytanie najpierw filtruje elementy robocze według StoryPoint gt 5, agreguje wyniki według ścieżki, a na koniec filtruje wynik według StoryPoints gt 2. W tej kolejności oceny zapytanie zawsze zwraca pusty zestaw.

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)
    )

✔️ ROZWAŻ utworzenie struktury zapytania, aby było zgodne z kolejnością oceny OData

Ponieważ mieszanie $apply i filter klauzul w jednym zapytaniu może prowadzić do potencjalnych nieporozumień, zalecamy utworzenie struktury klauzul zapytania w celu dopasowania ich do kolejności oceny.

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

✔️ ROZWAŻ przejrzenie funkcji OData opisanych w adnotacjach metadanych

Jeśli nie masz pewności, które funkcje usługi OData obsługuje analiza danych, możesz wyszukać adnotacje w metadanych. Komitet techniczny OASIS Open Data Protocol (OData) w repozytorium GitHub TC utrzymuje listę dostępnych adnotacji.

Na przykład lista obsługiwanych funkcji filtru jest dostępna w Org.OData.Capabilities.V1.FilterFunctions adnotacji w kontenerze jednostki.

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

Inną przydatną adnotacją jest Org.OData.Capabilities.V1.ExpandRestrictions, która wyjaśnia, które właściwości nawigacji nie można użyć w klauzuli $expand . Na przykład poniższa adnotacja wyjaśnia, że Revisions w WorkItems zestawie jednostek nie można rozszerzyć.

<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>