Interroger le graphe de jumeaux Azure Digital Twins
Cet article fournit des exemples de requête et des instructions sur l’utilisation du langage de requête Azure Digital Twins pour interroger votre graphe de jumeaux afin d’obtenir des informations. (Pour une présentation du langage de requête, consultez Langage de requête.)
L’article contient des exemples de requête qui illustrent la structure du langage de requête et les opérations de requête courantes pour des jumeaux numériques. Il décrit également comment exécuter vos requêtes une fois que vous les avez écrites, à l’aide de l’API de requête Azure Digital Twins ou d’un KIT de développement logiciel (SDK).
Notes
Si vous exécutez les exemples de requête ci-dessous avec un appel d’API ou de SDK, vous devez condenser le texte de la requête sur une seule ligne.
Documentation de référence
Les informations de référence sur le langage de requête se trouvent sous Informations de référence dans la table des matières de gauche de la documentation Azure Digital Twins. Vous pouvez également accéder directement aux sections de référence en utilisant les liens ci-dessous :
Montrer tous les jumeaux numériques
Voici la requête de base qui retourne la liste de tous les jumeaux numériques dans l’instance :
SELECT * FROM DIGITALTWINS
Requête par propriété
Obtenir les jumeaux numériques d’après leurs propriétés (y compris l’ID et les métadonnées) :
SELECT *
FROM DIGITALTWINS T
WHERE T.firmwareVersion = '1.1'
AND T.$dtId in ['123', '456']
AND T.Temperature = 70
Comme le montre la requête ci-dessus, l’ID d’un jumeau numérique est interrogé à l’aide du champ de métadonnées $dtId
.
Conseil
Si vous utilisez Cloud Shell pour exécuter une requête avec des champs de métadonnées qui commencent par $
, vous devez placer le $
dans une séquence d’échappement avec une barre oblique inverse pour signaler à Cloud Shell qu’il ne s’agit pas d’une variable et qu’il doit être consommé comme littéral dans le texte de la requête.
Vous pouvez également obtenir des jumeaux en fonction de la définition ou non d’une certaine propriété. Voici une requête qui récupère les jumeaux dont la propriété Location
a été définie :
SELECT * FROM DIGITALTWINS WHERE IS_DEFINED(Location)
Cette requête vous permet d’obtenir des jumeaux par le biais de leurs propriétés tag
, comme décrit dans Ajouter des étiquettes à des jumeaux numériques. Voici une requête qui récupère tous les jumeaux étiquetés avec red
:
SELECT * FROM DIGITALTWINS WHERE IS_DEFINED(tags.red)
Vous pouvez également obtenir des jumeaux selon le type d’une propriété. Voici une requête qui récupère les jumeaux dont la propriété Temperature
est un nombre :
SELECT * FROM DIGITALTWINS T WHERE IS_NUMBER(T.Temperature)
Propriétés du mappage de requêtes
Si une propriété est du type Map
complexe , vous pouvez utiliser les clés de mappage et les valeurs directement dans la requête, comme suit :
SELECT * FROM DIGITALTWINS T WHERE T.<propertyName>.<mapKey> = '<mapValue>'
Si la clé de carte commence par un caractère numérique, vous devez encapsuler la clé entre crochets doubles ([[<mapKey>]]
) pour l’échapper dans la requête, comme dans la stratégie d’interrogation avec des mots clés réservés.
Requête par modèle
L’opérateur IS_OF_MODEL
peut être utilisé pour filtrer en fonction du modèle de jumeau.
Il prend en compte l’héritage et le contrôle de version du modèle et prend la valeur true
pour un jumeau donné si le jumeau remplit l’une des conditions suivantes :
- Le jumeau implémente directement le modèle fourni à
IS_OF_MODEL()
, et le numéro de version du modèle sur le jumeau est supérieur ou égal au numéro de version du modèle fourni. - Le jumeau implémente un modèle qui étend le modèle fourni à
IS_OF_MODEL()
, et le numéro de version du modèle étendu du jumeau est supérieur ou égal au numéro de version du modèle fourni.
Par exemple, si vous interrogez les jumeaux du modèle dtmi:example:widget;4
, la requête renvoie tous les jumeaux basés sur la version 4 ou ultérieure du modèle widget, ainsi que les jumeaux basés sur la version 4 ou ultérieure de tous les modèles qui héritent du widget.
IS_OF_MODEL
peut prendre plusieurs paramètres différents, et le reste de cette section est dédié à ses différentes options de surcharge.
L’utilisation la plus simple de IS_OF_MODEL
ne prend qu’un paramètre twinTypeName
: IS_OF_MODEL(twinTypeName)
.
Voici un exemple de requête qui transmet une valeur dans ce paramètre :
SELECT * FROM DIGITALTWINS WHERE IS_OF_MODEL('dtmi:example:thing;1')
Pour spécifier une collection de jumeaux à rechercher lorsqu’il en existe plusieurs (par exemple, lorsqu’un JOIN
est utilisé), ajoutez le paramètre twinCollection
: IS_OF_MODEL(twinCollection, twinTypeName)
.
Voici un exemple de requête qui transmet une valeur dans ce paramètre :
SELECT * FROM DIGITALTWINS DT WHERE IS_OF_MODEL(DT, 'dtmi:example:thing;1')
Pour effectuer une correspondance exacte, ajoutez le paramètre exact
: IS_OF_MODEL(twinTypeName, exact)
.
Voici un exemple de requête qui transmet une valeur dans ce paramètre :
SELECT * FROM DIGITALTWINS WHERE IS_OF_MODEL('dtmi:example:thing;1', exact)
Vous pouvez également passer les trois arguments ensemble : IS_OF_MODEL(twinCollection, twinTypeName, exact)
.
Voici un exemple de requête spécifiant une valeur pour les trois paramètres :
SELECT * FROM DIGITALTWINS DT WHERE IS_OF_MODEL(DT, 'dtmi:example:thing;1', exact)
Requête par relation
Lorsque vous effectuez une interrogation basée sur les relations des jumeaux numériques, sachez que le langage du magasin de requêtes d’Azure Digital Twins présente une syntaxe spéciale.
Les relations sont tirées (pull) puis ajoutées à l’étendue de la requête dans la clause FROM
. Contrairement aux langages de type SQL « classiques », chaque expression de cette clause FROM
n’est pas une table. La clause FROM
exprime plutôt un parcours des relations entre les entités. Pour parcourir les relations, Azure Digital Twins utilise une version personnalisée de JOIN
.
Rappelez-vous qu’avec les capacités de modèle d’Azure Digital Twins, les relations n’existent pas indépendamment des jumeaux, ce qui signifie que les relations ici ne peuvent être interrogées indépendamment et doivent être liées à un jumeau.
Pour refléter ce fait, le mot clé RELATED
est utilisé dans la clause JOIN
pour extraire l’ensemble d’un certain type de relation provenant de la collection de jumeaux. La requête doit ensuite filtrer dans la clause WHERE
pour indiquer le(s) jumeau(x) spécifique(s) à utiliser dans la requête de relation (à l’aide des valeurs $dtId
des jumeaux).
Les sections suivantes fournissent des exemples.
Requête de relation de base
Voici un exemple de requête basée sur les relations. Cet extrait de code sélectionne tous les jumeaux numériques dont la propriété ID
a la valeur ABC
, ainsi que tous les jumeaux numériques associés à ces jumeaux via une relation contains
.
SELECT T, CT
FROM DIGITALTWINS T
JOIN CT RELATED T.contains
WHERE T.$dtId = 'ABC'
Le type de relation (contains
dans l’exemple ci-dessus) est indiqué par le champ name
de la relation dans sa définition DTDL.
Notes
Le développeur n’a pas besoin de mettre en corrélation ce JOIN
avec une valeur de clé dans la clause WHERE
(ni de spécifier une valeur de clé inline avec la définition JOIN
). Cette corrélation est calculée automatiquement par le système, puisque les propriétés de relation identifient l’entité cible.
Interroger selon la source ou la cible d’une relation
Vous pouvez utiliser la structure de requête de relation pour identifier un jumeau numérique qui est la source ou la cible d’une relation.
Par exemple, vous pouvez commencer avec un jumeau source et suivre ses relations pour trouver les jumeaux cibles des relations. Voici un exemple de requête qui recherche les jumeaux cibles des relations de feeds
provenant du jumeau source du jumeau.
SELECT target
FROM DIGITALTWINS source
JOIN target RELATED source.feeds
WHERE source.$dtId = 'source-twin'
Vous pouvez également commencer avec la cible de la relation et effectuer le suivi de la relation pour retrouver le jumeau source. Voici un exemple de requête qui permet de trouver le jumeau source d’une relation de feeds
avec le jumeau cible du jumeau.
SELECT source
FROM DIGITALTWINS source
JOIN target RELATED source.feeds
WHERE target.$dtId = 'target-twin'
Interroger les propriétés d’une relation
De même qu’il est possible de décrire les propriétés des jumeaux numériques via DTDL, les relations peuvent elles aussi avoir des propriétés. Vous pouvez interroger les jumeaux selon les propriétés de leurs relations.
Le langage d’Azure Digital Twins permet le filtrage et la projection des relations, en affectant un alias à la relation dans la clause JOIN
.
Prenons l’exemple d’une relation servicedBy
qui comprendrait une propriété reportedCondition
. Dans la requête ci-dessous, cette relation se voit attribuer l’alias R
afin de référencer sa propriété.
SELECT T, SBT, R
FROM DIGITALTWINS T
JOIN SBT RELATED T.servicedBy R
WHERE T.$dtId = 'ABC'
AND R.reportedCondition = 'clean'
Dans l’exemple ci-dessus, notez que reportedCondition
est une propriété de la relation servicedBy
(et non d’un jumeau numérique ayant une relation servicedBy
).
Interroger avec plusieurs clauses JOIN
Jusqu’à cinq clauses JOIN
sont prises en charge dans une même requête, ce qui vous permet de traverser plusieurs niveaux de relations à la fois.
Pour effectuer une requête à plusieurs niveaux de la relation, utilisez une instruction FROM
suivie de N instructions JOIN
, où les instructions JOIN
expriment les relations basées sur le résultat d’une instruction FROM
ou JOIN
précédente.
Voici un exemple de requête à plusieurs JOIN, qui permet d’obtenir toutes les ampoules contenues dans les panneaux lumineux des pièces 1 et 2.
SELECT LightBulb
FROM DIGITALTWINS Room
JOIN LightPanel RELATED Room.contains
JOIN LightBulb RELATED LightPanel.contains
WHERE IS_OF_MODEL(LightPanel, 'dtmi:contoso:com:lightpanel;1')
AND IS_OF_MODEL(LightBulb, 'dtmi:contoso:com:lightbulb ;1')
AND Room.$dtId IN ['room1', 'room2']
Compter les éléments
Vous pouvez compter le nombre d’éléments dans un jeu de résultats à l’aide de la clause Select COUNT
:
SELECT COUNT()
FROM DIGITALTWINS
Ajoutez une clause WHERE
pour compter le nombre d’éléments qui répondent à un certain critère. Voici quelques exemples de comptage avec un filtre appliqué en fonction du type de modèle de jumeau (pour plus d’informations sur cette syntaxe, consultez Requête par modèle ci-dessous) :
SELECT COUNT()
FROM DIGITALTWINS
WHERE IS_OF_MODEL('dtmi:sample:Room;1')
SELECT COUNT()
FROM DIGITALTWINS c
WHERE IS_OF_MODEL('dtmi:sample:Room;1') AND c.Capacity > 20
Vous pouvez également utiliser COUNT
avec la clause JOIN
. Voici une requête qui compte toutes les ampoules contenues dans les panneaux lumineux des salles 1 et 2 :
SELECT COUNT()
FROM DIGITALTWINS Room
JOIN LightPanel RELATED Room.contains
JOIN LightBulb RELATED LightPanel.contains
WHERE IS_OF_MODEL(LightPanel, 'dtmi:contoso:com:lightpanel;1')
AND IS_OF_MODEL(LightBulb, 'dtmi:contoso:com:lightbulb;1')
AND Room.$dtId IN ['room1', 'room2']
Filtrer les résultats : sélectionner les meilleurs éléments
Vous pouvez sélectionner les meilleurs éléments dans une requête à l’aide de la clause Select TOP
.
SELECT TOP (5)
FROM DIGITALTWINS
WHERE ...
Filtrer les résultats : spécifier un jeu de retour avec des projections
En utilisant des projections dans l’instruction SELECT
, vous pouvez choisir les colonnes qui sont renvoyées par une requête. La projection est désormais prise en charge pour les propriétés primitives et complexes. Pour plus d’informations sur les projections avec Azure Digital Twins, consultez la documentation de référence sur la clause SELECT.
Voici un exemple de requête qui utilise la projection pour retourner les jumeaux et les relations. La requête ci-dessous projette Consumer, Factory et Edge dans un scénario où une Factory avec l’ID ABC
est liée au Consumer via une relation Factory.customer
, et cette relation est présentée en tant que Edge
.
SELECT Consumer, Factory, Edge
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'
Vous pouvez également utiliser la projection pour retourner une propriété d’un jumeau. La requête suivante projette la propriété Name
des Consumers associés à la Factory avec l’ID ABC
via une relation de Factory.customer
.
SELECT Consumer.name
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'
Vous pouvez également utiliser la projection pour retourner une propriété d’une relation. Comme dans l’exemple précédent, la requête suivante projette la propriété Name
des Consumers associés à la Factory avec un ID ABC
via une relation de Factory.customer
. Elle retourne maintenant également deux propriétés de cette relation : prop1
et prop2
. Pour ce faire, elle nomme la relation Edge
et collecte ses propriétés.
SELECT Consumer.name, Edge.prop1, Edge.prop2, Factory.area
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'
Vous pouvez également utiliser des alias pour simplifier les requêtes avec projection.
La requête suivante effectue les mêmes opérations que l’exemple précédent, mais elle associe les noms de propriété à consumerName
, first
, second
et factoryArea
.
SELECT Consumer.name AS consumerName, Edge.prop1 AS first, Edge.prop2 AS second, Factory.area AS factoryArea
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'
Voici une requête similaire qui interroge le même jeu que ci-dessus, mais projette uniquement la propriété Consumer.name
en tant que consumerName
et projette la fabrique complète en tant que jumeau.
SELECT Consumer.name AS consumerName, Factory
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'
Créer des requêtes efficaces avec l’opérateur IN
Vous pouvez réduire considérablement le nombre de requêtes dont vous avez besoin en générant un tableau de jumeaux et en l’interrogeant à l’aide de l’opérateur IN
.
Par exemple, imaginons un scénario dans lequel des immeubles comprennent des étages, et ces étages comprennent des pièces. Pour rechercher des salles chauffées dans un immeuble, vous pouvez suivre ces étapes.
Recherchez les étages de l’immeuble en fonction de la relation
contains
.SELECT Floor FROM DIGITALTWINS Building JOIN Floor RELATED Building.contains WHERE Building.$dtId = @buildingId
Pour trouver des pièces, au lieu de prendre les étages un par un et d’exécuter une requête
JOIN
afin de rechercher les pièces de chacun d’eux, vous pouvez interroger une collection d’étages de l’immeuble (nommée Floor dans la requête ci-dessous).Dans l’application cliente :
var floors = "['floor1','floor2', ..'floorn']";
Dans la requête :
SELECT Room FROM DIGITALTWINS Floor JOIN Room RELATED Floor.contains WHERE Floor.$dtId IN ['floor1','floor2', ..'floorn'] AND Room. Temperature > 72 AND IS_OF_MODEL(Room, 'dtmi:com:contoso:Room;1')
Autres exemples de requêtes composées
Vous pouvez combiner un des types de requête ci-dessus avec des opérateurs de combinaison pour inclure plus de détails dans une seule requête. Voici quelques autres exemples de requêtes composées qui interrogent plusieurs types de descripteur de jumeau à la fois.
- Parmi les appareils qui équipent Room 123 (la salle 123), retournez les appareils MxChip qui remplissent le rôle d’Operator (opérateur)
SELECT device FROM DIGITALTWINS space JOIN device RELATED space.has WHERE space.$dtid = 'Room 123' AND device.$metadata.model = 'dtmi:contoso:com:DigitalTwins:MxChip:3' AND has.role = 'Operator'
- Récupérez les jumeaux qui présentent une relation nommée
Contains
(Contient) avec un autre jumeau dont l’ID estid1
SELECT Room FROM DIGITALTWINS Room JOIN Thermostat RELATED Room.Contains WHERE Thermostat.$dtId = 'id1'
- Récupérez toutes les salles de ce modèle de salle qui sont contenues dans floor11 (l’étage11)
SELECT Room FROM DIGITALTWINS Floor JOIN Room RELATED Floor.Contains WHERE Floor.$dtId = 'floor11' AND IS_OF_MODEL(Room, 'dtmi:contoso:com:DigitalTwins:Room;1')
Exécuter des requêtes avec l’API
Une fois que vous avez choisi une chaîne de requête, exécutez-la en appelant l’API de requête.
Vous pouvez appeler l’API directement ou utiliser l’un des SDK disponibles pour Azure Digital Twins.
L’extrait de code suivant illustre l’appel au SDK .NET (C#) à partir de l’application cliente :
// Run a query for all twins
string query = "SELECT * FROM DIGITALTWINS";
AsyncPageable<BasicDigitalTwin> result = client.QueryAsync<BasicDigitalTwin>(query);
La requête utilisée dans cet appel retourne une liste de jumeaux numériques, que l’exemple ci-dessus représente avec des objets BasicDigitalTwin. Le type de retour de vos données pour chaque requête dépend des termes que vous spécifiez avec l’ instruction SELECT
:
- Les requêtes qui commencent par
SELECT * FROM ...
retournent une liste de jumeaux numériques (qui peuvent être sérialisés sous la forme d’objetsBasicDigitalTwin
ou d’autres types de jumeaux numériques personnalisés que vous avez peut-être créés). - Les requêtes qui commencent au format
SELECT <A>, <B>, <C> FROM ...
retournent un dictionnaire avec des clés<A>
,<B>
et<C>
. - D’autres formats d’instructions
SELECT
peuvent être élaborés pour retourner des données personnalisées. Vous pouvez envisager de créer vos propres classes pour gérer des jeux de résultats personnalisés.
Requête avec pagination
Les appels de requête prennent en charge la pagination. Voici un exemple complet qui utilise BasicDigitalTwin
en tant que type de résultat de requête avec gestion des erreurs et pagination :
AsyncPageable<BasicDigitalTwin> result = client.QueryAsync<BasicDigitalTwin>("Select * From DigitalTwins");
try
{
await foreach (BasicDigitalTwin twin in result)
{
// You can include your own logic to print the result
// The logic below prints the twin's ID and contents
Console.WriteLine($"Twin ID: {twin.Id} \nTwin data");
foreach (KeyValuePair<string, object> kvp in twin.Contents)
{
Console.WriteLine($"{kvp.Key} {kvp.Value}");
}
}
}
catch (RequestFailedException ex)
{
Console.WriteLine($"Error {ex.Status}, {ex.ErrorCode}, {ex.Message}");
throw;
}
Étapes suivantes
Découvrez les API et SDK Azure Digital Twins, y compris l’API de requête qui est utilisée pour exécuter les requêtes de cet article.