Instructions relatives aux requêtes OData Analytics pour Azure DevOps
Azure DevOps Services | Azure DevOps Server 2022 | Azure DevOps Server 2019
Les développeurs d’extensions peuvent bénéficier en suivant les instructions fournies dans cet article pour concevoir des requêtes OData efficaces sur Analytics pour Azure DevOps. Le suivi de ces instructions permet de s’assurer que les requêtes présentent de bonnes performances pour le temps d’exécution et la consommation des ressources. Les requêtes qui ne respectent pas ces instructions peuvent entraîner des performances médiocres, avec des temps d’attente longs de rapport, des requêtes qui dépassent la consommation de ressources autorisée ou des blocages de service.
Remarque
Le service Analytics est automatiquement activé et pris en charge en production pour tous les services Azure DevOps. L’intégration de Power BI et l’accès au flux OData du service Analytics sont généralement disponibles. Nous vous encourageons à l’utiliser et à nous faire part de vos commentaires.
Les données disponibles dépendent de la version. La dernière version prise en charge est v2.0
, et la dernière version d’évaluation est v4.0-preview
. Pour plus d’informations, consultez gestion des versions de l’API OData.
Remarque
Le service Analytics est automatiquement installé et pris en charge en production pour toutes les nouvelles collections de projets pour Azure DevOps Server 2020 et versions ultérieures. L’intégration de Power BI et l’accès au flux OData du service Analytics sont généralement disponibles. Nous vous encourageons à l’utiliser et à nous faire part de vos commentaires. Si vous avez effectué une mise à niveau à partir d’Azure DevOps Server 2019, vous pouvez installer le service Analytics pendant la mise à niveau.
Les données disponibles dépendent de la version. La dernière version prise en charge est v2.0
, et la dernière version d’évaluation est v4.0-preview
. Pour plus d’informations, consultez gestion des versions de l’API OData.
Remarque
Le service Analytics est en préversion pour Azure DevOps Server 2019. Vous pouvez l’activer ou l’installer pour une collection de projets. L’intégration de Power BI et l’accès au flux OData du service Analytics sont en préversion. Nous vous encourageons à l’utiliser et à nous faire part de vos commentaires.
Les données disponibles dépendent de la version. La dernière version prise en charge est v2.0
, et la dernière version d’évaluation est v4.0-preview
. Pour plus d’informations, consultez gestion des versions de l’API OData.
Ces recommandations sont précédées des termes DO, CONSIDER, AVOID et DON’T. Les règles restrictives appliquées par Analytics contiennent le préfixe [BLOCKED]. Vous devez comprendre les compromis entre différentes solutions. Dans certaines circonstances, vous pouvez avoir des exigences de données qui vous obligent à violer une ou plusieurs instructions. Ces cas doivent être rares. Nous vous recommandons d’avoir une raison claire et convaincante pour ces décisions.
Conseil
Les exemples présentés dans ce document sont basés sur une URL Azure DevOps Services. Utilisez des substitutions pour les versions locales.
https://{servername}:{port}/tfs/{OrganizationName}/{ProjectName}/_odata/{version}/
Messages d’erreur et d’avertissement
✔️ Vérifier les avertissements de réponse OData
Chaque requête que vous exécutez est vérifiée par rapport à un ensemble de règles prédéfinies. Les violations retournent la réponse OData suivante @vsts.warnings
. Passez en revue ces avertissements, car ils fournissent des informations actuelles et contextuelles sur la façon d’améliorer votre requête.
{
"@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."
],
...
}
✔️ Vérifier les messages d’erreur OData
Les requêtes qui violent une règle d’erreur OData entraînent une réponse ayant échoué avec un code d’état 400 (Requête incorrecte). Les messages associés n’apparaissent pas dans la @vsts.warnings
propriété. Au lieu de cela, ils génèrent un message d’erreur dans la message
propriété dans la réponse 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."
}
}
Restrictions
Pratiques conseillées
- ✔️ Limitez la requête au ou aux projets auquel vous avez accès
- ✔️ Spécifiez le filtre de projet à l’intérieur de la
$expand
clause si votre extension peut inclure des données dans d’autres projets potentiellement inaccessibles - ✔️ Attendez ou arrêtez l’opération si votre requête dépasse les limites d’utilisation
- ✔️ Patientez ou arrêtez l’opération en cas d’échec de votre requête avec un délai d’expiration
- ✔️ DO include
DateSK
ouDateValue
column ingroupby
clause when you aggregate over snapshot tables - ✔️ DO adresse explicitement des entités avec des clauses de filtre
- ✔️ Utiliser l’ensemble
WorkItemRevisions
d’entités pour charger toutes les révisions d’un élément de travail donné - ✔️ Utiliser le point de terminaison batch pour les requêtes longues
- ✔️ Spécifier le fuseau horaire lors du filtrage sur les colonnes de date
Consider
Bloqué
- ❌ [BLOQUÉ] N’utilisez pas d’entités d’instantané pour quoi que ce soit d’autre que les agrégations
- ❌ [BLOQUÉ] N’utilisez pas de clés d’entité dans les chemins d’accès aux ressources pour l’adressage d’entité
- ❌[BLOQUÉ] NE pas développer
Revisions
l’entitéWorkItem
- ❌ [BLOQUÉ] NE PAS regrouper sur des colonnes distinctes
- ❌ [BLOQUÉ] N’utilisez
countdistinct
pas l’agrégation - ❌ [BLOQUÉ] N’utilisez pas de point de terminaison batch pour l’envoi de plusieurs requêtes
- ❌ [BLOQUÉ] N’utilisez pas de requêtes qui entraînent plus de 800 colonnes
Éviter
- ❌ ÉVITER les agrégations qui peuvent entraîner un dépassement arithmétique
- ❌ ÉVITER de créer des requêtes longues
✔️ Limitez la requête au ou aux projets auquel vous avez accès
Si votre requête cible les données d’un projet auquel vous n’avez pas accès, la requête retourne un message « Accès au projet refusé ». Pour vous assurer que vous disposez d’un accès, vérifiez que votre autorisation View Analytics est définie sur Autoriser pour tous les projets que vous interrogez. Pour plus d’informations, consultez Autorisations requises pour accéder à Analytics.
Si vous n’avez pas accès à un projet, le message suivant s’affiche :
Les résultats de la requête incluent des données dans un ou plusieurs projets pour lesquels vous n’avez pas accès. Ajoutez un ou plusieurs filtres de projets pour spécifier le ou les projets auquel vous avez accès dans l’entité « WorkItems ». Si vous utilisez des propriétés $expand ou de navigation, le filtre de projet est requis pour ces entités.
Pour contourner ce problème, vous pouvez ajouter explicitement un filtre de projet ou utiliser le point de terminaison étendu au projet, comme expliqué plus loin dans cet article.
Par exemple, la requête suivante extrait des éléments de travail qui appartiennent à des projets nommés {projectSK1}
et {projectSK2}
.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=ProjectSK eq {projectSK1} or ProjectSK eq {projectSK2}
&$select=WorkItemId, Title
✔️ Spécifiez le filtre de projet à l’intérieur de la $expand
clause si votre extension peut inclure des données dans d’autres projets potentiellement inaccessibles
Lorsque vous développez des propriétés de navigation, il est possible que vous finissent par référencer des données à partir d’autres projets inaccessibles. Si vous référencez des données inaccessibles, vous recevez le même message d’erreur répertorié précédemment, « Les résultats de la requête incluent des données dans un ou plusieurs projets... ». De même, vous pouvez résoudre ce problème en ajoutant des filtres de projet explicites pour contrôler les données développées.
Vous pouvez le faire dans la clause régulière $filter
pour les propriétés de navigation simples. Par exemple, la requête suivante demande WorkItemLinks
explicitement où le lien et sa cible existent dans le même projet.
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)
Au lieu de cela, vous pouvez déplacer le filtre pour $filter
développer l’option dans la $expand
clause. Toutefois, elle modifie la sémantique de la requête. Par exemple, la requête suivante obtient tous les liens d’un projet donné et développe conditionnellement la cible uniquement s’il existe dans le même projet. Bien qu’elle soit valide, cette approche peut entraîner une confusion, car il peut être difficile de déterminer si une propriété n’est pas développée, car elle est null
ou parce qu’elle a été filtrée. Utilisez cette solution uniquement si vous avez vraiment besoin de ce comportement particulier.
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)
L’option $filter
expand est utile lorsque vous utilisez la propriété expand collection telle que Children
dans WorkItems
l’ensemble d’entités. Par exemple, la requête suivante retourne tous les éléments de travail d’un projet donné, ainsi que tous leurs enfants appartenant au même projet.
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)
Spécifiez le filtre si vous développez l’une des propriétés suivantes :
WorkItems
jeu d’entités :Parent
,Children
WorkItemLinks
jeu d’entités :TargetWorkItem
.
✔️ ENVISAGEZ d’interroger à l’aide du point de terminaison étendu au projet
Si vous êtes intéressé par les données d’un seul projet, nous vous recommandons d’utiliser le point de terminaison OData étendu au projet (/{ProjectName}/_odata/v1.0
). Il évite les problèmes décrits dans les deux sections précédentes et filtre implicitement les données dans le projet un, le jeu d’entités référencé et toutes les propriétés de navigation développées.
Avec cette simplification, les requêtes de la section précédente peuvent être réécrites dans le formulaire suivant. Non seulement le filtre dans la clause expand a disparu, mais il n’y a pas besoin du filtre sur le jeu d’entités principal.
https://analytics.dev.azure.com/{OrganizationName}/{ProjectName}/_odata/{version}//WorkItemLinks?
&$select=LinkTypeReferenceName, SourceWorkItemId, TargetWorkItemId
&$expand=TargetWorkItem($select=WorkItemId, Title)
La requête pour les enfants d’éléments de travail est également beaucoup plus courte et plus simple.
https://analytics.dev.azure.com/{OrganizationName}/{ProjectName}/_odata/{version}//WorkItems?
&$select=WorkItemId, Title
&$expand=Children($select=WorkItemId, Title)
Vous pouvez appliquer cette solution uniquement lorsque votre focus est des données d’un seul projet. Pour la création de rapports entre projets, vous devez utiliser des stratégies de filtrage décrites dans les sections précédentes.
✔️ Attendez ou arrêtez l’opération si votre requête dépasse les limites d’utilisation
Si vous exécutez de nombreuses requêtes ou que les requêtes nécessitent de nombreuses ressources à exécuter, vous pouvez dépasser les limites de service et être temporairement bloqués. Si vous dépassez les limites du service, arrêtez votre opération, car il est probable que la requête suivante que vous envoyez échoue avec le même message d’erreur.
La demande a été bloquée en raison du dépassement de l’utilisation de la ressource « {resource} » dans l’espace de noms « {espace de noms} ».
Pour plus d’informations sur la limitation du débit, consultez Limites de débit. Pour savoir comment concevoir des requêtes OData efficaces, reportez-vous aux instructions de performances plus loin dans cet article.
✔️ Patientez ou arrêtez l’opération en cas d’échec de votre requête avec un délai d’expiration
Comme pour dépasser les limites d’utilisation, vous devez attendre ou arrêter l’opération si votre requête rencontre un délai d’expiration. Il peut signaler un problème temporaire. Vous pouvez donc réessayer une fois pour voir si le problème est résolu. Toutefois, les délais d’expiration persistants indiquent que la requête est probablement trop coûteuse à exécuter. De nouvelles tentatives entraînent uniquement un dépassement des limites d’utilisation et vous êtes bloqué.
TF400733 : la demande a été annulée : la demande a dépassé le délai d’expiration de la demande, réessayez.
Les délais d’expiration indiquent qu’une requête nécessite une optimisation. Pour savoir comment concevoir des requêtes OData efficaces, consultez les recommandations en matière de performances plus loin dans cet article.
❌ [BLOQUÉ] N’utilisez pas d’entités d’instantané pour quoi que ce soit d’autre que les agrégations
Les jeux d’entités d’instantanés avec le Snapshot
suffixe sont spéciaux, car ils sont modélisés comme instantanés quotidiens. Vous pouvez les utiliser pour obtenir un état d’entités tel qu’elles étaient à la fin de chaque jour dans le passé. Par exemple, si vous avez interrogé WorkItemSnapshot
et filtré sur un seul WorkItemId
enregistrement, vous obtenez un enregistrement pour chaque jour depuis la création de l’élément de travail. Le chargement direct de toutes ces données serait coûteux et probablement dépasserait les limites d’utilisation et serait bloqué. Toutefois, les agrégations sur ces entités sont autorisées et recommandées. En fait, les jeux d’entités d’instantané ont été conçus avec des scénarios d’agrégation à l’esprit.
Par exemple, la requête suivante obtient le nombre d’éléments de travail comme date pour observer comment elle a augmenté en janvier 2020.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemSnapshot?
$apply=
filter(DateSK ge 20200101 and DateSK le 20200131)/
groupby((DateSK), aggregate($count as Count))
Pour plus d’informations sur les agrégations, consultez Données d’agrégation.
✔️ DO include DateSK
ou DateValue
column in groupby
clause when you aggregate over snapshot tables
Étant donné que toutes les entités d’instantané sont modélisées en tant que tables d’instantanés quotidiennes, vous devez toujours inclure l’une des propriétés de jour (DateSK
ou DateValue
) dans la clause de regroupement. Sinon, le résultat peut apparaître incorrectement gonflé.
Par exemple, si vous n’avez regroupé WorkItemSnapshot
que par AssignedTo
propriété et agrègez-le avec le nombre, tous les nombres d’éléments de travail attribués aux personnes seraient multipliés par le nombre de jours où chaque affectation était active. Bien que vous ayez peut-être une situation où il s’agit du résultat souhaité, ces cas sont rares.
❌ [BLOQUÉ] N’utilisez pas de clés d’entité dans les chemins d’accès aux ressources pour l’adressage d’entité
La syntaxe OData permet d’accéder à une entité particulière en incluant ses clés directement dans les segments d’URL. Pour plus d’informations, consultez OData version 4.0. Partie 2 : Conventions d’URL - 4.3 Entités d’adressage. Bien qu’OData autorise ce type d’adressage, Analytics le bloque. L’inclusion dans une requête entraîne l’erreur suivante.
La requête spécifiée dans l’URI n’est pas valide. Analytics ne prend pas en charge la navigation de clé ou de propriété comme WorkItems(Id) ou WorkItem(Id)/AssignedTo. Si vous obtenez cette erreur dans PowerBI, réécrivez votre requête pour éviter le pliage incorrect qui provoque un problème N+1.
Comme les indicateurs de messages d’erreur, certains outils clients peuvent abuser de l’adressage direct d’entité. Au lieu de charger toutes les données dans une seule requête, ces clients peuvent choisir d’interroger chaque entité indépendamment. Cette pratique est déconseillée, car elle peut entraîner un nombre élevé de demandes. Au lieu de cela, nous vous recommandons d’utiliser l’adressage d’entité explicite, comme expliqué dans la section suivante.
✔️ DO adresse explicitement des entités avec des clauses de filtre
Si vous souhaitez extraire des données pour une entité unique, vous devez utiliser la même approche que pour une collection d’entités et définir explicitement des filtres dans la $filter
clause.
Par exemple, la requête suivante obtient un élément de travail unique par son identificateur.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=WorkItemId eq {id}
&$select=WorkItemId, Title
Si vous ne savez pas quelles propriétés vous devez inclure dans un tel filtre, vous pouvez la rechercher dans les métadonnées. Consultez Construire des requêtes OData pour Analytics, composants d’URL pour interroger les métadonnées. Les propriétés se trouvent dans l’élément Key
du EntityType
. Par exemple, WorkItemId
et Revision
sont des colonnes clés pour l’entité WorkItemRevision
.
<EntityType Name="WorkItemRevision">
<Key>
<PropertyRef Name="WorkItemId"/>
<PropertyRef Name="Revision"/>
</Key>
[...]
</EntityType>
❌[BLOQUÉ] NE pas développer Revisions
l’entité WorkItem
Le modèle de données Analytics interdit certains types d’expansions. L’un d’eux, qui peut être surprenant à certains, est la Revisions
propriété de collection sur l’entité WorkItem
. Si vous essayez de développer cette propriété, vous recevez le message d’erreur suivant.
La requête spécifiée dans l’URI n’est pas valide. La propriété « Revisions » ne peut pas être utilisée dans l’option de requête $expand.
Cette restriction a été mise en place pour encourager tout le monde à utiliser la solution recommandée, qui extrait les révisions WorkItemRevisions
comme expliqué dans la section suivante.
✔️ Utiliser l’ensemble WorkItemRevisions
d’entités pour charger toutes les révisions d’un élément de travail donné
Utilisez WorkItemRevisions
chaque fois que vous souhaitez récupérer l’historique complet d’un élément de travail ou d’une collection d’éléments de travail.
Par exemple, la requête suivante retourne toutes les révisions d’un élément de travail avec l’identificateur {id}
.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemRevisions?
$filter=WorkItemId eq {id}
&$select=WorkItemId, Title
Si vous vous souciez de l’historique complet de tous les éléments de travail qui correspondent à certains critères, exprimez-le à l’aide d’un filtre sur la propriété de WorkItem
navigation. Par exemple, la requête suivante obtient toutes les révisions de tous les éléments de travail actuellement actifs.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItemRevisions?
$filter=WorkItem/State eq 'Active'
&$select=WorkItemId, Title
❌ [BLOQUÉ] NE PAS regrouper sur des colonnes distinctes
Vous utilisez une opération de regroupement pour réduire le nombre d’enregistrements. L’utilisation de colonnes distinctes dans la groupby
clause indique un problème et la requête échoue immédiatement. Si vous rencontrez accidentellement cette situation, vous recevez le message d’erreur suivant.
Une ou plusieurs des colonnes spécifiées dans la clause groupby de cette requête ne sont pas recommandées.
Pour résoudre ce problème, supprimez la colonne distincte de la groupby
clause.
❌ [BLOQUÉ] N’utilisez countdistinct
pas l’agrégation
Analytics ne prend pas en charge la countdistinct
fonction, même si OData le fait. Même si nous prévoyons d’ajouter du support à l’avenir, il n’est actuellement pas disponible. Une requête qui contient cette fonction retourne le message d’erreur suivant.
Les requêtes qui appliquent un nombre distinct avec une agrégation ne sont pas prises en charge.
❌ ÉVITER les agrégations qui peuvent entraîner un dépassement arithmétique
Dans de rares cas, une requête d’agrégation peut rencontrer des problèmes de dépassement arithmétique. Par exemple, il peut se produire lorsque vous additionnez certaines propriétés numériques qui ne sont pas destinées à la somme, comme StackRank
dans les entités d’élément de travail. Étant donné que l’extension OData pour la norme d’agrégation de données ne permet pas de convertir une propriété en un autre type, la seule façon de résoudre ce problème consiste à supprimer la propriété problématique de l’agrégation.
✔️ Utiliser le point de terminaison batch pour les requêtes longues
Vous pouvez rencontrer des problèmes avec de longues requêtes. En particulier, des problèmes peuvent se produire quand :
- Vous interrogez un projet avec de nombreux champs personnalisés.
- Votre requête est construite par programmation.
La limite actuelle des requêtes OData envoyées est HTTP GET
de 3 000 caractères. Si vous la dépassez, vous obtenez une réponse « 404 Introuvable ».
HTTP/1.1 404 Not Found
Content-Length: 0
Pour résoudre ce problème, utilisez le point de terminaison de lot OData, comme expliqué dans la spécification, OData Version 4.0. Partie 1 : Protocole - Requêtes par lots 11.7. La fonctionnalité Batch a principalement été conçue pour regrouper plusieurs opérations dans une charge utile de requête unique HTTP
, mais vous pouvez également l’utiliser comme solution de contournement pour la limitation de longueur de requête. En envoyant une HTTP POST
requête, vous pouvez passer une requête d’une longueur arbitraire et le service l’interprète correctement.
❌ [BLOQUÉ] N’utilisez pas de point de terminaison batch pour l’envoi de plusieurs requêtes
Nous limitons l’utilisation du point de terminaison de traitement par lots de plusieurs requêtes. Une seule requête ne peut toujours avoir qu’une seule requête. Si vous essayez d’envoyer un lot de plusieurs requêtes, l’opération échoue avec le message d’erreur suivant. La seule solution consiste à fractionner des requêtes en plusieurs requêtes.
Analytics ne prend pas en charge le traitement de plusieurs opérations que contient le message batch actuel. Analytics utilise le lot OData pour prendre en charge les requêtes POST, mais nécessite que vous limitiez l’opération à une seule requête.
❌ [BLOQUÉ] N’utilisez pas de requêtes qui entraînent plus de 800 colonnes
Nous limitons les requêtes qui entraînent plus de 800 colonnes. Si vous n’êtes pas suffisamment sélectif dans les colonnes retournées par votre requête, vous pouvez recevoir le message d’erreur suivant.
VS403670 : la requête spécifiée retourne des colonnes « N » supérieures à la limite autorisée de 800 colonnes. Utilisez des options de $select explicites (y compris dans le $expand) pour limiter le nombre de colonnes.
Ajoutez une clause $select à votre requête et $expand opérations dans votre requête pour éviter de dépasser cette limite.
❌ ÉVITER de créer des requêtes longues
Nous vous recommandons d’évaluer votre approche chaque fois que vous construisez une longue requête. Bien qu’il existe de nombreux scénarios nécessitant une longue requête (par exemple, des filtres complexes ou une longue liste de propriétés), ils fournissent généralement un indicateur précoce d’une conception non optimale.
Lorsque votre requête contient de nombreuses clés d’entité dans la requête (par exemple, WorkItemId eq {id 1} or WorkItemId eq {id 2} or ...
), vous pouvez probablement la réécrire. Au lieu de passer les identificateurs, essayez de définir d’autres critères qui sélectionnent le même ensemble d’entités. Parfois, vous devrez peut-être modifier votre processus (par exemple, ajouter un nouveau champ ou une balise), mais cela vaut généralement la peine. Les requêtes qui utilisent des filtres plus abstraits sont plus faciles à gérer et peuvent mieux fonctionner.
Un autre scénario qui tend à générer des requêtes longues se produit lorsque vous incluez de nombreuses dates individuelles (par exemple). DateSK eq {dateSK 1} or DateSK eq {dateSK 2} or ...
Recherchez un autre modèle que vous pouvez utiliser pour créer un filtre plus abstrait. Par exemple, la requête suivante retourne tous les éléments de travail créés le lundi.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedOn/DayOfWeek eq 2
&$select=WorkItemId, Title, State
✔️ Spécifier le fuseau horaire lors du filtrage sur les colonnes de date
Le fuseau horaire (Edm.DateTimeOffset
) expose toutes les informations de date et d’heure avec un décalage qui correspond aux paramètres de fuseau horaire de l’organisation. Ces données sont précises et simples à interpréter en même temps. Une autre conséquence non discrète est que tous les filtres doivent également transmettre les informations de fuseau horaire. Si vous l’ignorez, vous obtenez le message d’erreur suivant.
La requête spécifiée dans l’URI n’est pas valide. Aucun décalage datetime n’a été spécifié. Utilisez l’un de ces formats AAAA-MM-JJZ pour spécifier tout depuis minuit ou aaaa-MM-jjThh :mm-hh :mm (représentation standard ISO 8601 de dates et d’heures) pour spécifier le décalage.
Pour résoudre ce problème, ajoutez les informations de fuseau horaire. Par exemple, en supposant que l’organisation est configurée pour afficher les données dans le fuseau horaire « (UTC-08:00) Pacific Time (ÉTATS-Unis et Canada), la requête suivante obtient tous les éléments de travail créés depuis le début de 2020.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedDate ge 2020-01-01T00:00:00-08:00
&$select=WorkItemId, Title, State
La même solution fonctionne pour les fuseaux horaires avec des décalages positifs, cependant, le caractère plus (+
) a une signification spéciale dans l’URI et vous devez le gérer correctement. Si vous spécifiez 2020-01-01T00:00:00+08:00
(avec un +
caractère) comme point de départ, vous obtenez l’erreur suivante.
La requête spécifiée dans l’URI n’est pas valide. Erreur de syntaxe à la position 31 dans « CreatedDate ge 2020-01-01T0000 08:00 ».
Pour le résoudre, remplacez le +
caractère par sa version encodée. %2B
Par exemple, en supposant que l’organisation est configurée pour afficher les données dans le fuseau horaire « (UTC+08:00) Beijing, Chongqing, Hong Kong, Urumqi », la requête suivante retourne tous les éléments de travail créés depuis le début de 2020.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedDate ge 2020-01-01T00:00:00%2B08:00
&$select=WorkItemId, Title, State
Une autre approche consiste à utiliser les propriétés de clé de substitution de date, car elles ne conservent pas les informations de fuseau horaire. Par exemple, la requête suivante retourne tous les éléments de travail créés depuis le début de 2020, quels que soient les paramètres de l’organisation.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedDateSK ge 20200101
&$select=WorkItemId, Title, State
Recommandations sur les performances
Pratiques conseillées
- ✔️ Mesurer l’effet de l’implémentation d’une directive sur les performances
- ✔️ Utiliser des extensions d’agrégation
- ✔️ Spécifier des colonnes dans la
$select
clause - ✔️ Spécifier des colonnes dans l’option développer à l’intérieur
$select
de la$expand
clause - ✔️ Définissez un filtre
RevisedDateSK
lorsque vous interrogez des données d’éléments de travail historiques (WorkItemRevisions
ouWorkItemSnapshot
des jeux d’entités) - ✔️ Utiliser des instantanés hebdomadaires ou mensuels pour les requêtes de tendance qui s’étendent sur une longue période
- ✔️ Utiliser la
Tags
propriété de collection sur les éléments de travail lors du filtrage par balises - ✔️
TagNames
Utilisez la propriété si vous souhaitez afficher toutes les étiquettes d’un élément de travail sous forme de texte - ✔️ Utiliser la pagination pilotée par le serveur
- ✔️ Utiliser l’option
$top
de requête pour limiter le nombre d’enregistrements
N’est pas
- ❌ N’utilisez pas et ne utilisez
tolower
pas detoupper
fonctions pour effectuer une comparaison sans respect de la casse - ❌ N’utilisez pas l’extension sans limite avec
$levels=max
- ❌N’utilisez pas et
$skip
n’utilisez$top
pas les options de requête pour implémenter la pagination pilotée par le client
Consider
- ✔️ ENVISAGEZ d’écrire des requêtes pour retourner un petit nombre d’enregistrements
- ✔️ ENVISAGEZ de limiter le nombre de propriétés sélectionnées au minimum
- ✔️ ENVISAGEZ de filtrer sur les propriétés de clé de substitution de date (
DateSK
suffixe) - ✔️ ENVISAGEZ de filtrer sur les colonnes clés de substitution
- ✔️ ENVISAGEZ de transmettre
vsts.analytics.maxsize
la préférence dans l’en-tête
Éviter
✔️ Mesurer l’effet de l’implémentation d’une directive sur les performances
Comme avec les recommandations de performances, vous ne devez pas les implémenter aveuglement. Au lieu de cela, capturez toujours la ligne de base et mesurez l’effet des modifications que vous apportez. Toutes les lignes directrices ont été créées en fonction des interactions avec les clients d’Analytics qui avaient des exigences et des défis spécifiques. Ces recommandations ont été considérées comme générales et potentiellement utiles pour toute personne qui conçoit des requêtes similaires. Toutefois, dans de rares cas, le fait de suivre les instructions ne pouvait avoir aucun effet ou même un effet négatif sur les performances. Vous devez mesurer la différence pour la remarquer. Si cela se produit, fournissez des commentaires dans le portail de la Communauté des développeurs.
Il existe de nombreuses options pour mesurer les performances. La plus simple consiste à exécuter deux versions de la même requête directement dans le navigateur. Observez le temps nécessaire aux outils de développement. Par exemple, vous pouvez utiliser le panneau Réseau dans les outils de développement Microsoft Edge F12. Une autre option consiste à capturer ces informations à l’aide de l’outil de débogueur Web Fiddler.
Quelle que soit votre approche, exécutez les deux requêtes plusieurs fois. Par exemple, exécutez les requêtes 30 fois chacune pour avoir un ensemble d’échantillons suffisamment volumineux. Ensuite, déterminez les caractéristiques de performances. Analytics suit l’architecture mutualisée. Par conséquent, d’autres opérations se produisant en même temps peuvent affecter la durée de vos requêtes.
✔️ Utiliser des extensions d’agrégation
De loin, la meilleure chose que vous pouvez faire pour améliorer les performances de vos requêtes consiste à utiliser l’extension d’agrégation - Extension OData pour l’agrégation de données. Avec l’extension d’agrégation, demandez au service de synthétiser le serveur de données et de retourner une réponse plus petite que ce que vous pouvez extraire en appliquant le même côté client de fonction. Enfin, Analytics est optimisé pour ce type de requêtes. Par conséquent, utilisez-le.
Pour plus d’informations, consultez Données agrégées.
✔️ Spécifier des colonnes dans la $select
clause
Spécifiez les colonnes qui vous intéressent dans la $select
clause. L’analytique est basée sur une technologie Columnstore Index . Cela signifie que les données sont à la fois le stockage et le traitement des requêtes est basé sur des colonnes. En réduisant l’ensemble de propriétés, vous référencez dans $select
la clause vous pouvez réduire le nombre de colonnes qui doivent être analysées et améliorer les performances globales de la requête.
Par exemple, la requête suivante spécifie les colonnes des éléments de travail.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$select=WorkItemId, Title, State
Remarque
Azure DevOps prend en charge la personnalisation des processus. Certains administrateurs utilisent cette fonctionnalité et créent des centaines de champs personnalisés. Si vous omettez la $select
clause, votre requête retourne tous les champs, y compris les champs personnalisés.
✔️ Spécifier des colonnes dans l’option développer à l’intérieur $select
de la $expand
clause
Comme pour les instructions de $select
clause, spécifiez les propriétés de l’option $select
expand dans la $expand
clause. Il est facile d’oublier, mais si vous l’omettez, votre réponse contient toutes les propriétés de l’objet développé.
Par exemple, la requête suivante spécifie les colonnes de l’élément de travail et de son parent.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$select=WorkItemId, Title, State
&$expand=Parent($select=WorkItemId, Title, State)
✔️ Définissez un filtre RevisedDateSK
lorsque vous interrogez des données d’éléments de travail historiques (WorkItemRevisions
ou WorkItemSnapshot
des jeux d’entités)
Lorsque vous interrogez des données historiques, les chances sont que vous êtes intéressé par la période la plus récente (par exemple, 30 jours, 90 jours). En raison de la façon dont les entités d’éléments de travail sont implémentées, il existe un moyen pratique d’écrire ces requêtes pour obtenir de bonnes performances. Chaque fois que vous mettez à jour un élément de travail, il crée une nouvelle révision et enregistre cette action dans le System.RevisedDate
champ, ce qui le rend parfait pour les filtres d’historique.
Dans Analytics, la date révisée est affichée dans les RevisedDate
propriétés (Edm.DateTimeOffset
) et RevisedDateSK
(Edm.Int32
). Pour des performances optimales, utilisez-la. Il s’agit de la clé de substitution de date et représente la date à laquelle une révision a été créée ou qu’elle a null
pour les révisions actives et incomplètes. Si vous souhaitez toutes les dates depuis l’inclus {startDate}
, ajoutez le filtre suivant à votre requête.
RevisedDateSK eq null or RevisedDateSK gt {startDateSK}
Par exemple, la requête suivante retourne le nombre d’éléments de travail pour chaque jour depuis le début de 2020. Notez qu’en dehors du filtre évident sur DateSK
la colonne, il y a un deuxième filtre sur RevisedDateSK
. Bien qu’il semble redondant, il aide le moteur de requête à filtrer les révisions qui ne sont pas dans l’étendue et améliore considérablement les performances des requêtes.
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)
)
Remarque
Nous avons fourni cette recommandation lorsque nous travaillions sur les widgets Burndown. Initialement, nous avons défini des filtres uniquement pour DateSK
mais nous n’avons pas pu obtenir cette requête pour s’adapter correctement aux organisations avec des jeux de données volumineux. Lors du profilage des requêtes, nous avons remarqué que DateSK
cela ne filtre pas correctement les révisions. Seulement après l’ajout d’un filtre, RevisedDateSK
nous avons pu obtenir de bonnes performances à grande échelle.
~ Équipe produit
✔️ Utiliser des instantanés hebdomadaires ou mensuels pour les requêtes de tendance qui s’étendent sur une longue période
Par défaut, toutes les tables d’instantanés sont modélisées en tant que tables de faits d’instantané quotidiennes. Si vous interrogez un intervalle de temps, il obtient une valeur pour chaque jour. Les intervalles de temps longs entraînent un grand nombre d’enregistrements. Si vous n’avez pas besoin d’une telle précision, vous pouvez utiliser des instantanés hebdomadaires ou même mensuels.
Vous pouvez le faire avec d’autres expressions de filtre pour supprimer des jours qui ne terminent pas une semaine ou un mois donné. Utilisez la propriété, qui a été ajoutée à Analytics avec ce scénario à l’esprit IsLastDayOfPeriod
. Cette propriété est de type Microsoft.VisualStudio.Services.Analytics.Model.Period
et peut déterminer si un jour se termine dans différentes périodes (par exemple, semaines, mois, etc.).
<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>
Étant Microsoft.VisualStudio.Services.Analytics.Model.Period
donné qu’il est défini comme énumération avec des indicateurs, utilisez l’opérateur OData has
et spécifiez le type complet pour les littéraux de période.
IsLastDayOfPeriod has Microsoft.VisualStudio.Services.Analytics.Model.Period'Month'
Par exemple, la requête suivante retourne un nombre d’éléments de travail qui ont été définis le dernier jour de chaque mois.
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)
)
✔️ Utiliser la Tags
propriété de collection sur les éléments de travail lors du filtrage par balises
Vous pouvez utiliser la TagNames
propriété avec la contains
fonction pour déterminer si un travail a été marqué avec une balise spécifique. Toutefois, cette approche peut entraîner des requêtes lentes, en particulier lors de la vérification de plusieurs balises en même temps. Pour des performances et des résultats optimaux, utilisez plutôt la Tags
propriété de navigation.
Par exemple, la requête suivante obtient tous les éléments de travail marqués avec un {tag}
.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=Tags/any(t:t/TagName eq '{tag}')
&$select=WorkItemId, Title, State
Cette approche fonctionne également très bien lorsque vous devez filtrer sur plusieurs balises. Par exemple, la requête suivante retourne tous les éléments de travail marqués avec {tag1}
ou {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
Vous pouvez également combiner ces filtres avec un opérateur « et ». Par exemple, la requête suivante obtient tous les éléments de travail marqués avec les deux {tag1}
et {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
Utilisez la propriété si vous souhaitez afficher toutes les étiquettes d’un élément de travail sous forme de texte
La propriété Tags
de navigation, décrite dans la section précédente, est idéale pour le filtrage. Toutefois, l’utilisation de ces derniers présente certains défis à mesure que la requête retourne des balises dans une collection imbriquée. Le modèle de données contient également une TagNames
propriété primitive (Edm.String
), que nous avons ajoutée pour simplifier les scénarios de consommation de balises. Il s’agit d’une valeur de texte unique qui contient une liste de toutes les balises combinées à un séparateur de points-virgules « ; ». Utilisez cette propriété lorsque vous vous souciez tous d’afficher des balises ensemble. Vous pouvez la combiner avec les filtres de balises décrits précédemment.
Par exemple, la requête suivante obtient tous les éléments de travail marqués avec un {tag}
. Elle retourne l’ID de l’élément de travail, le titre, l’état et une représentation textuelle des balises combinées.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=Tags/any(t:t/TagName eq '{tag}')
&$select=WorkItemId, Title, State, TagNames
Important
La propriété TagNames
a une limite de longueur de 1 024 caractères. Il contient un ensemble de balises qui correspondent à cette limite. Si un élément de travail a de nombreuses balises ou si les balises sont très longues, TagNames
ne contiennez pas le jeu complet et Tag
la propriété de navigation doit être utilisée à la place.
❌ N’utilisez pas et ne utilisez tolower
pas de toupper
fonctions pour effectuer une comparaison sans respect de la casse
Si vous avez travaillé avec d’autres systèmes, vous pouvez vous attendre à utiliser les fonctions ou toupper
les fonctions pour la comparaison qui ne respecte pas la tolower
casse. Avec Analytics, toutes les comparaisons de chaînes ne respectent pas la casse par défaut. Vous n’avez donc pas besoin d’appliquer de fonctions pour la gérer explicitement.
Par exemple, la requête suivante obtient tous les éléments de travail étiquetés avec « QUALITÉ », « qualité » ou toute autre combinaison de cas de ce mot.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=Tags/any(t:t/TagName eq 'quality')
&$select=WorkItemId, Title, State, TagNames
❌ N’utilisez pas l’extension sans limite avec $levels=max
OData a la possibilité de développer tous les niveaux d’une structure hiérarchique. Par exemple, le suivi des éléments de travail comporte certaines entités où une extension sans limite peut être appliquée. Cette opération fonctionne uniquement pour les organisations avec une petite quantité de données. Il ne s’adapte pas bien aux jeux de données plus volumineux. Ne l’utilisez pas du tout si :
- Vous utilisez des jeux de données volumineux.
- Vous développez un widget et vous n’avez aucun contrôle sur l’emplacement où le widget est installé.
✔️ Utiliser la pagination pilotée par le serveur
Si vous demandez un ensemble trop volumineux pour être envoyé dans une seule réponse, Analytics applique la pagination. La réponse inclut uniquement un ensemble partiel et un lien qui permet de récupérer le jeu partiel suivant d’éléments. Cette stratégie est décrite dans la spécification OData - OData Version 4.0. Partie 1 : Protocole - Pagination pilotée par le serveur. En permettant au service de contrôler la pagination, vous obtenez les meilleures performances, car la skiptoken
conception a été soigneusement adaptée à chaque entité afin qu’elle soit aussi efficace que possible.
Le lien vers la page suivante est inclus dans la @odata.nextLink
propriété.
{
"@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"}
Remarque
La plupart des clients OData existants peuvent gérer automatiquement la pagination pilotée par le serveur. Par exemple, cette stratégie est déjà utilisée par les outils suivants : Power BI, SQL Server Integration Services et Azure Data Factory.
❌N’utilisez pas et $skip
n’utilisez $top
pas les options de requête pour implémenter la pagination pilotée par le client
Avec d’autres API REST, vous avez peut-être implémenté la pagination pilotée par le client et $top
$skip
les options de requête. Ne les utilisez pas avec Analytics. Il existe plusieurs problèmes avec cette approche et les performances sont l’un d’eux. Au lieu de cela, adoptez la stratégie de pagination pilotée par le serveur décrite dans la section précédente.
✔️ Utiliser l’option $top
de requête pour limiter le nombre d’enregistrements
L’option $top
de requête n’est déconseillée que lorsqu’elle est utilisée avec $skip
. Si, dans votre scénario de création de rapports, vous n’avez besoin que d’un sous-ensemble d’enregistrements (par exemple, exemple), il est recommandé d’utiliser l’option $top
de requête. En outre, si vous avez besoin de classer les enregistrements selon certains critères, vous devez toujours utiliser $top
en combinaison avec $orderby
pour obtenir un résultat stable avec les enregistrements classés les plus hauts.
✔️ ENVISAGEZ d’écrire une requête pour retourner un petit nombre d’enregistrements
L’écriture d’une requête pour retourner un petit nombre d’enregistrements est la directive la plus intuitive. Visez toujours à extraire uniquement les données qui vous intéressent vraiment. Pour ce faire, vous pouvez tirer parti des puissantes fonctionnalités de filtrage disponibles dans le langage de requête OData.
✔️ ENVISAGEZ de limiter le nombre de propriétés sélectionnées à un minimum
Certains administrateurs de projet personnalisent fortement leurs processus en ajoutant des champs personnalisés. La personnalisation intensive peut entraîner des problèmes de performances lors de l’extraction de toutes les colonnes disponibles sur des entités larges (par exemple, WorkItems
). L’analytique est basée sur une technologie Columnstore Index . Cela signifie que les données sont à la fois le stockage et le traitement des requêtes est basé sur des colonnes. Par conséquent, plus les propriétés qu’une requête référence, plus il est coûteux de traiter. Visez toujours à limiter l’ensemble des propriétés de vos requêtes à ce que vous avez vraiment à propos de votre scénario de création de rapports.
✔️ ENVISAGEZ de filtrer sur les propriétés de clé de substitution de date (DateSK
suffixe)
Il existe de nombreuses façons de définir un filtre de date. Vous pouvez filtrer directement sur la propriété date (par exemple, CreatedDate
), son équivalent de navigation (par exemple, CreatedOnDate
) ou sa représentation de clé de substitution (par exemple, CreatedDate
). La dernière option génère les meilleures performances et est préférée lorsque les exigences de création de rapports l’autorisent.
Par exemple, la requête suivante obtient tous les éléments de travail créés depuis le début de 2020.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedDateSK ge 20200101
✔️ ENVISAGEZ de filtrer sur les colonnes clés de substitution
Si vous souhaitez filtrer les données sur la valeur d’un objet associé (par exemple, en filtrant un élément de travail sur le nom du projet), vous avez toujours deux choix. Vous pouvez utiliser la propriété de navigation (par exemple) Project/ProjectName
ou capturer la clé de substitution avant et l’utiliser directement dans la requête (par exemple, ProjectSK
).
Si vous créez un widget, nous vous recommandons d’utiliser cette dernière option. Lorsque la clé est passée dans le cadre de la requête, le nombre d’ensembles d’entités qui doivent être tactiles est réduit et les performances s’améliorent.
Par exemple, les filtres WorkItems
de requête suivants utilisent ProjectSK
la propriété plutôt que la propriété de Project/ProjectName
navigation.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=ProjectSK eq {projectSK}
❌AVOID using Parent
, , or Revisions
Children
properties in the $filter
or $expand
clauses
Les éléments de travail sont les entités les plus coûteuses dans l’ensemble du modèle de données. Ils ont plusieurs propriétés de navigation que vous pouvez utiliser pour accéder aux éléments de travail associés : Parent
, Children
, Revisions
. Toutefois, chaque fois que vous les utilisez dans une requête, attendez-vous à une baisse des performances. Demandez toujours si vous avez vraiment besoin de l’une de ces propriétés et éventuellement de mettre à jour votre conception.
Par exemple, au lieu de développer Parent
, vous pouvez récupérer davantage d’éléments de travail et utiliser ParentWorkItemId
la propriété pour reconstruire le côté client de la hiérarchie complète. Effectuez cette optimisation au cas par cas.
✔️ ENVISAGEZ de transmettre VSTS.Analytics.MaxSize
la préférence dans l’en-tête
Lorsque vous exécutez une requête, vous ne connaissez pas le nombre d’enregistrements retournés par la requête. Envoyez une autre requête avec des agrégations ou suivez tous les liens suivants et récupérez l’intégralité du jeu de données. Analytics respecte les VSTS.Analytics.MaxSize
préférences, ce qui vous permet d’échouer rapidement dans les instances que le jeu de données est plus grand que ce que votre client peut accepter.
Cette option est utile dans les scénarios d’exportation de données. Pour l’utiliser, vous devez ajouter Prefer
un en-tête à votre requête HTTP et définir VSTS.Analytics.MaxSize
sur une valeur non négative. La VSTS.Analytics.MaxSize
valeur représente le nombre maximal d’enregistrements que vous pouvez accepter. Si vous définissez la valeur zéro, une valeur par défaut de 200 K est utilisée.
Par exemple, la requête suivante retourne des éléments de travail si le jeu de données est plus petit ou égal à 1 000 enregistrements.
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}
Si le jeu de données dépasse la limite de 1 000 enregistrements, la requête échoue immédiatement avec l’erreur suivante.
Le résultat de la requête contient 1 296 lignes et dépasse la taille maximale autorisée de 1 000. Réduisez le nombre d’enregistrements en appliquant des filtres supplémentaires
Pour plus d’informations sur la définition de la taille maximale de la page, consultez la propriété ODataPreferenceHeader.MaxPageSize.
Instructions relatives au style de requête
- ✔️ Utiliser une
$count
propriété virtuelle dans les méthodes d’agrégation - ❌ ÉVITER d’utiliser
$count
la propriété virtuelle dans le segment d’URL - ❌ ÉVITER le mélange
$apply
et$filter
les clauses dans une seule requête - ✔️ ENVISAGEZ d’utiliser des alias de paramètre pour séparer les parties volatiles de la requête
- ✔️ ENVISAGEZ de structurer votre requête pour qu’elle corresponde à l’ordre d’évaluation OData
- ✔️ ENVISAGEZ d’examiner les fonctionnalités OData décrites dans les annotations de métadonnées
✔️ Utiliser une $count
propriété virtuelle dans les méthodes d’agrégation
Certaines entités exposent Count
la propriété. Ils facilitent certains scénarios de création de rapports lorsque les données sont exportées vers un autre stockage. Toutefois, vous ne devez pas utiliser ces colonnes dans les agrégations dans les requêtes OData. Utilisez plutôt la $count
propriété virtuelle.
Par exemple, la requête suivante retourne le nombre total d’éléments de travail.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$apply=aggregate($count as Count)
❌ ÉVITER d’utiliser $count
la propriété virtuelle dans le segment d’URL
Bien que la norme OData vous permet d’utiliser $count
la propriété virtuelle pour les jeux d’entités (par exemple, _odata/v1.0/WorkItems/$count
), tous les clients ne peuvent pas interpréter correctement la réponse. Il est donc recommandé d’utiliser des agrégations à la place.
Par exemple, la requête suivante retourne le nombre total d’éléments de travail.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$apply=aggregate($count as Count)
✔️ ENVISAGEZ d’utiliser des alias de paramètre pour séparer les parties volatiles de la requête
Les alias de paramètres fournissent une solution élégante pour extraire des parties volatiles telles que des valeurs de paramètres à partir du texte de la requête principale. Vous pouvez les utiliser dans des expressions qui évaluent :
- Valeur primitive
- Valeur complexe
- Collection de valeurs primitives ou complexes.
Pour plus d’informations, consultez OData version 4.0. Partie 2 : Conventions d’URL - Alias de paramètre 5.1.1.13. Les paramètres sont utiles lorsque le texte de requête est utilisé comme modèle qui peut être instancié avec des valeurs fournies par l’utilisateur.
Par exemple, la requête suivante utilise @createdDateSK
un paramètre pour séparer la valeur de l’expression de filtre.
https://analytics.dev.azure.com/{OrganizationName}/_odata/{version}/WorkItems?
$filter=CreatedDateSK ge @createdDateSK
&$select=WorkItemId, Title, State
&@createdDateSK=20200101
❌ ÉVITER le mélange $apply
et $filter
les clauses dans une seule requête
Si vous souhaitez ajouter filter
à votre requête, vous avez deux options. Vous pouvez le faire avec la $filter
clause ou la $apply=filter()
combinaison. Chacune de ces options fonctionne parfaitement sur elle-même, mais la combinaison de ces options peut entraîner des résultats inattendus.
Malgré l’attente que l’on peut avoir, OData définit clairement un ordre de l’évaluation. En outre, la $apply
clause a la priorité sur $filter
. Pour cette raison, vous devez choisir l’une ou l’autre, mais éviter ces deux options de filtre dans une seule requête. Il est important que les requêtes soient générées automatiquement.
Par exemple, la requête suivante filtre d’abord les éléments de travail par StoryPoint gt 5
, agrège les résultats par chemin d’accès et enfin filtre le résultat par StoryPoints gt 2
. Avec cet ordre d’évaluation, la requête retourne toujours un jeu vide.
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)
)
✔️ ENVISAGEZ de structurer votre requête pour qu’elle corresponde à l’ordre d’évaluation OData
Étant donné que le mélange $apply
et filter
les clauses dans une seule requête peuvent entraîner une confusion potentielle, nous vous recommandons de structurer vos clauses de requête pour qu’elles correspondent à l’ordre d’évaluation.
$apply
$filter
$orderby
$expand
$select
$skip
$top
✔️ ENVISAGEZ d’examiner les fonctionnalités OData décrites dans les annotations de métadonnées
Lorsque vous ne savez pas quelles fonctionnalités OData prennent en charge, vous pouvez rechercher des annotations dans les métadonnées. Le comité technique OASIS Open Data Protocol (OData) dans un dépôt GitHub TC gère une liste d’annotations disponibles.
Par exemple, la liste des fonctions de filtre prises en charge est disponible dans Org.OData.Capabilities.V1.FilterFunctions
l’annotation sur le conteneur d’entités.
<Annotation Term="Org.OData.Capabilities.V1.FilterFunctions">
<Collection>
<String>contains</String>
<String>endswith</String>
[...]
</Collection>
</Annotation>
Une autre annotation utile est Org.OData.Capabilities.V1.ExpandRestrictions
, qui explique les propriétés de navigation que vous ne pouvez pas utiliser dans la $expand
clause. Par exemple, l’annotation suivante explique que Revisions
dans l’ensemble WorkItems
d’entités ne peut pas être développé.
<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>