Consulta del grafo gemelo de Azure Digital Twins

En este artículo se ofrecen ejemplos de consultas e instrucciones sobre el uso del lenguaje de consultas de Azure Digital Twins para consultar un grafo de gemelos para obtener información. (Para obtener una introducción al lenguaje de consulta, consulte Acerca del lenguaje de consulta para Azure Digital Twins).

El artículo contiene consultas de ejemplo que muestran la estructura del lenguaje de consulta y las operaciones de consulta habituales para los gemelos digitales. También se describe cómo ejecutar las consultas después de escribirlas, mediante la API de consulta de Azure Digital Twins o un SDK.

Nota

Si ejecuta las consultas de ejemplo siguientes con la llamada a una API o un SDK, deberá condensar el texto de la consulta en una sola línea.

Documentación de referencia

La referencia del Lenguaje de consulta se puede encontrar debajo de Referencia en el índice de la izquierda de la documentación de Azure Digital Twins. También puede ir directamente a las secciones de referencia mediante los vínculos a continuación:

Mostrar todos los gemelos digitales

Esta es una consulta básica que devolverá una lista de todos los gemelos digitales de la instancia:

SELECT * FROM DIGITALTWINS

Consulta por propiedad

Obtenga instancias de Digital Twins por propiedades (incluidos el identificador y los metadatos):

SELECT  *
FROM DIGITALTWINS T  
WHERE T.firmwareVersion = '1.1'
AND T.$dtId in ['123', '456']
AND T.Temperature = 70

Como se muestra en la consulta anterior, el identificador de un gemelo digital se consulta mediante el campo de metadatos $dtId.

Sugerencia

Cuando se usa Cloud Shell para ejecutar una consulta con campos de metadatos que comienzan por $, se debe usar $ como carácter de escape para que Cloud Shell sepa que no es una variable y se debe consumir como literal en el texto de la consulta.

También puede obtener instancias de Digital Twins en función de si una propiedad determinada está definida. Esta es una consulta que obtiene los gemelos digitales que tienen la propiedad Location definida:

SELECT *​ FROM DIGITALTWINS WHERE IS_DEFINED(Location)

Esta consulta puede ayudar a obtener gemelos digitales por sus propiedades tag, como se describe en Incorporación de etiquetas a gemelos digitales. Esta es una consulta que obtiene todos los gemelos digitales con la etiqueta red:

SELECT * FROM DIGITALTWINS WHERE IS_DEFINED(tags.red)

También puede obtener instancias de Digital Twins en función del tipo de una propiedad. Esta es una consulta que obtiene los gemelos digitales cuya propiedad Temperature es un número:

SELECT * FROM DIGITALTWINS​ T WHERE IS_NUMBER(T.Temperature)

Propiedades de asignación de consultas

Si una propiedad es del tipo Mapcomplejo , puede usar las claves y los valores de asignación directamente en la consulta, de la siguiente manera:

SELECT * FROM DIGITALTWINS​ T WHERE T.<propertyName>.<mapKey> = '<mapValue>'

Si la clave de mapa comienza con un carácter numérico, deberá encapsular la clave entre corchetes dobles ([[<mapKey>]]) para escaparla en la consulta, de forma similar a la estrategia para realizar consultas con palabras clave reservadas.

Consulta por modelo

El operador IS_OF_MODEL se puede utilizar para filtrar en función del modelo del gemelo.

Tiene en cuenta la herencia y el control de versiones del modelo, y se evalúa como true para un gemelo dado si este cumple cualquiera de estas condiciones:

  • El gemelo implementa directamente el modelo proporcionado a IS_OF_MODEL() y el número de versión del modelo en el gemelo es mayor o igual que el número de versión del modelo proporcionado.
  • El gemelo implementa un modelo que amplía el modelo proporcionado a IS_OF_MODEL() y el número de versión del modelo extendido del gemelo es mayor o igual que el número de versión del modelo proporcionado.

Por ejemplo, si consulta los gemelos del modelo dtmi:example:widget;4, la consulta devolverá todos los gemelos basados en la versión 4 o superior del modelo de widget, y también los gemelos basados en la versión 4 o superior de los modelos que heredan del widget.

IS_OF_MODEL puede aceptar varios parámetros diferentes, y el resto de esta sección se dedica a sus distintas opciones de sobrecarga.

El uso más simple de IS_OF_MODEL solo toma un parámetro twinTypeName: IS_OF_MODEL(twinTypeName). A continuación, se muestra un ejemplo de consulta que pasa un valor en este parámetro:

SELECT * FROM DIGITALTWINS WHERE IS_OF_MODEL('dtmi:example:thing;1')

Para especificar una colección de gemelos para buscar cuando hay más de uno (como cuando se usa JOIN), agregue el parámetro twinCollection: IS_OF_MODEL(twinCollection, twinTypeName). A continuación, se muestra un ejemplo de consulta que agrega un valor en este parámetro:

SELECT * FROM DIGITALTWINS DT WHERE IS_OF_MODEL(DT, 'dtmi:example:thing;1')

Para realizar una coincidencia exacta, agregue el parámetro exact: IS_OF_MODEL(twinTypeName, exact). A continuación, se muestra un ejemplo de consulta que agrega un valor en este parámetro:

SELECT * FROM DIGITALTWINS WHERE IS_OF_MODEL('dtmi:example:thing;1', exact)

También puede pasar los tres argumentos juntos: IS_OF_MODEL(twinCollection, twinTypeName, exact). A continuación, se muestra un ejemplo de consulta que especifica un valor para los tres parámetros:

SELECT * FROM DIGITALTWINS DT WHERE IS_OF_MODEL(DT, 'dtmi:example:thing;1', exact)

Consulta por relación

Al realizar consultas basadas en relaciones de Digital Twins, el lenguaje de consultas de Azure Digital Twins tiene una sintaxis especial.

Las relaciones se extraen en el ámbito de la consulta en la cláusula FROM. A diferencia de los lenguajes de tipo SQL "clásico", cada expresión de la cláusula FROM no es una tabla; en su lugar, la cláusula FROM expresa un recorrido de relación entre entidades. Para recorrer las relaciones, Azure Digital Twins usa una versión personalizada de JOIN.

Recuerde que, con las funcionalidades del modelo de Azure Digital Twins, las relaciones no existen independientemente de los gemelos, lo que significa que las relaciones aquí no se pueden consultar de forma independiente y deben estar vinculadas a un gemelo. Para reflejar este hecho, se usa la palabra clave RELATED en la cláusula JOIN para extraer el conjunto de un tipo determinado de relación procedente de la colección de gemelos. A continuación, la consulta debe filtrar en la cláusula WHERE para indicar qué gemelos específicos se usarán en la consulta de relación (mediante los valores de $dtId de los gemelos).

En las siguientes secciones se proporcionan ejemplos de su aspecto.

Consulta de relación básica

A continuación, se muestra un ejemplo de consulta basada en relaciones. Este fragmento de código selecciona todos los gemelos digitales con una propiedad ID de ABC y todos los gemelos digitales relacionados con estos gemelos digitales a través de una relación contains.

SELECT T, CT
FROM DIGITALTWINS T
JOIN CT RELATED T.contains
WHERE T.$dtId = 'ABC'

El tipo de la relación (contains en el ejemplo anterior) se indica mediante el campo name de la relación a partir de su definición DTDL.

Nota

El desarrollador no necesita poner en correlación esta operación JOIN con un valor de clave en la cláusula WHERE (ni especificar un valor de clave insertado con la definición de JOIN). El sistema calcula esta correlación automáticamente, ya que las propias propiedades de la relación identifican la entidad de destino.

Consulta por el origen o destino de una relación

Puede usar la estructura de consulta de la relación para identificar un gemelo digital que sea el origen o destino de una relación.

Por ejemplo, puede empezar con un gemelo de origen y seguir sus relaciones para buscar los gemelos de destino de las relaciones. Este es un ejemplo de una consulta que busca los gemelos de destino de las relaciones feeds que proceden del gemelo source-twin.

SELECT target 
FROM DIGITALTWINS source 
JOIN target RELATED source.feeds 
WHERE source.$dtId = 'source-twin'

También puede empezar con el destino de la relación y realizar un seguimiento de la relación para encontrar al gemelo de origen. Este es un ejemplo de una consulta que busca los gemelos de origen de las relaciones de feeds con el gemelo target-twin.

SELECT source 
FROM DIGITALTWINS source 
JOIN target RELATED source.feeds 
WHERE target.$dtId = 'target-twin'

Consulta de las propiedades de una relación

Del mismo modo que los gemelos digitales tienen propiedades que se describen a través de DTDL, las relaciones también pueden tener propiedades. Puede consultar instancias de Digital Twins en función de las propiedades de sus relaciones. El lenguaje de consultas de Azure Digital Twins permite filtrar y proyectar relaciones mediante la asignación de un alias a la relación dentro de la cláusula JOIN.

Como ejemplo, considere una relación servicedBy que tiene una propiedad reportedCondition. En la consulta siguiente, a esta relación se le asigna el alias R para hacer referencia a su propiedad.

SELECT T, SBT, R
FROM DIGITALTWINS T
JOIN SBT RELATED T.servicedBy R
WHERE T.$dtId = 'ABC'
AND R.reportedCondition = 'clean'

En el ejemplo anterior, observe cómo reportedCondition es una propiedad de la propia relación servicedBy (NO de un gemelo digital que tiene una relación servicedBy).

Consulta con varias combinaciones JOIN

Se admiten hasta cinco cláusulas JOIN en una sola consulta, lo que permite el recorrido de varios niveles de relaciones a la vez.

Para consultar varios niveles de relaciones, use una única instrucción FROM seguida de N instrucciones JOIN, donde las instrucciones JOIN expresan relaciones en el resultado de una instrucción FROM o JOIN anterior.

Este es un ejemplo de una consulta de varias combinaciones, que obtiene todas las bombillas contenidas en los paneles de luz de las salas 1 y 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']

Recuento de elementos

Puede contar el número de elementos de un conjunto de resultados mediante la cláusula Select COUNT:

SELECT COUNT()
FROM DIGITALTWINS

Agregue una cláusula WHERE para contar el número de elementos que cumplen determinados criterios. Estos son algunos ejemplos de recuento con un filtro aplicado basado en el tipo de modelo gemelo (para obtener más información sobre esta sintaxis, vea Consulta por modelo a continuación):

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

También puede usar COUNT junto con la cláusula JOIN. Esta es una consulta que cuenta todas las bombillas incluidas en los paneles de luz de los salones 1 y 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']

Resultados del filtro: seleccionar elementos principales

Puede seleccionar los diversos elementos "principales" en una consulta mediante la cláusula Select TOP.

SELECT TOP (5)
FROM DIGITALTWINS
WHERE ...

Resultados del filtro: especificación del conjunto de devoluciones con proyecciones

El uso de las proyecciones en la instrucción SELECT permite elegir las columnas que devolverá una consulta. Ahora se admite la proyección para propiedades primitivas y complejas. Para más información sobre las proyecciones con Azure Digital Twins, consulte la documentación de referencia de la cláusula SELECT.

Este es un ejemplo de una consulta que usa una proyección para devolver gemelos y relaciones. La siguiente consulta proyecta los valores de consumidor, fábrica y borde de un escenario en el que una fábrica con el identificador ABC está relacionada con el consumidor mediante una relación Factory.customer, y esa relación se presenta como el Edge.

SELECT Consumer, Factory, Edge
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'

También puede usar la proyección para devolver una propiedad de un gemelo. La siguiente consulta proyecta la propiedad Name de los Consumidores que están relacionados con la Fábrica con un identificador de ABC mediante una relación de Factory.customer.

SELECT Consumer.name
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'

También puede usar la proyección para devolver una propiedad de una relación. Al igual que en el ejemplo anterior, la siguiente consulta proyecta la propiedad Name de los Consumidores relacionados con la Fábrica con un identificador de ABC mediante una relación de Factory.customer; pero ahora también devuelve dos propiedades de esa relación, prop1 y prop2. Para ello, se asigna un nombre a la relación Edge y se recopilan sus propiedades.

SELECT Consumer.name, Edge.prop1, Edge.prop2, Factory.area
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'

También puede utilizar alias para simplificar las consultas con proyección.

La siguiente consulta realiza las mismas operaciones que el ejemplo anterior, pero asigna a los nombres de propiedades los alias consumerName, first, second y 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'

Esta es una consulta similar que consulta el mismo conjunto que en el caso anterior, pero solo proyecta la propiedad Consumer.name como consumerName y proyecta la Fábrica completa como un gemelo.

SELECT Consumer.name AS consumerName, Factory
FROM DIGITALTWINS Factory
JOIN Consumer RELATED Factory.customer Edge
WHERE Factory.$dtId = 'ABC'

Creación de consultas eficientes con el operador IN

Puede reducir significativamente el número de consultas que necesita si crea una matriz de gemelos y consulta con el operador IN.

Por ejemplo, considere un escenario en el que Buildings contenga a Floors y Floors contenga a Rooms. Una forma de buscar las habitaciones que estén activas dentro de un edificio, es seguir estos pasos.

  1. Busque los pisos en el edificio con la relación contains.

    SELECT Floor
    FROM DIGITALTWINS Building
    JOIN Floor RELATED Building.contains
    WHERE Building.$dtId = @buildingId
    
  2. Para buscar las habitaciones, en lugar de tener que considerar los pisos uno por uno y ejecutar una consulta JOIN para buscar las habitaciones de cada uno, puede realizar consultas con una colección de los pisos del edificio (con el nombre Floor en la consulta siguiente).

    En la aplicación cliente:

    var floors = "['floor1','floor2', ..'floorn']"; 
    

    En la consulta:

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

Otros ejemplos de consultas compuestas

Puede combinar cualquiera de los tipos de consulta anteriores mediante operadores de combinación con el fin de incluir más detalles en una sola consulta. A continuación, se muestran otros ejemplos de consultas compuestas que realizan consultas para más de un tipo de descriptor de gemelo a la vez.

  • De entre los dispositivos que tiene Room 123, se devuelven los dispositivos MxChip que tienen el rol de operador.
    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'
    
  • Se obtienen las instancias de Digital Twins que tienen una relación denominada Contains con otra instancia que tiene un identificador id1
    SELECT Room
    FROM DIGITALTWINS Room
    JOIN Thermostat RELATED Room.Contains
    WHERE Thermostat.$dtId = 'id1'
    
  • Se obtienen todas las salas de este modelo de sala contenidos en floor11
    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')
    

Ejecución de consultas con la API

Una vez que haya decidido una cadena de consulta, puede ejecutarla realizando una llamada a Query API.

Puede llamar a la API directamente, o bien usar uno de los SDK disponibles para Azure Digital Twins.

En el fragmento de código siguiente se muestra la llamada al SDK de .NET (C#) desde una aplicación cliente:

// Run a query for all twins   
string query = "SELECT * FROM DIGITALTWINS";
AsyncPageable<BasicDigitalTwin> result = client.QueryAsync<BasicDigitalTwin>(query);

La consulta utilizada en esta llamada devuelve una lista de gemelos digitales, que el ejemplo anterior representa con objetos BasicDigitalTwin. El tipo de valor devuelto de los datos para cada consulta dependerá de los términos que especifique con la instrucción SELECT:

  • Las consultas que comienzan por SELECT * FROM ... devolverán una lista de gemelos digitales (que se pueden serializar como objetos BasicDigitalTwin u otros tipos de gemelos digitales personalizados que haya creado).
  • Las consultas que comienzan con el formato SELECT <A>, <B>, <C> FROM ... devolverán un diccionario con las claves <A>, <B> y <C>.
  • Se pueden diseñar otros formatos de instrucciones SELECT para devolver datos personalizados. Considere la posibilidad de crear sus propias clases para administrar conjuntos de resultados personalizados.

Consulta con paginación

Las llamadas de consulta admiten la paginación. Este es un ejemplo completo del uso de BasicDigitalTwin como tipo de resultado de la consulta con control de errores y paginación:

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

Pasos siguientes

Obtenga más información sobre las API y los SDK de Azure Digital Twins, incluida Query API, que se usa para ejecutar las consultas de este artículo.