Consultar o grafo de gêmeos dos Gêmeos Digitais do Azure

Este artigo oferece exemplos de consulta e instruções para usar a linguagem de consulta dos Gêmeos Digitais do Azure a fim de consultar o grafo de gêmeos para obter informações. (Para obter uma introdução à linguagem de consulta, confira Linguagem de consulta.)

Este artigo contém exemplos que ilustram a estrutura da linguagem de consulta e as operações de consulta comuns para gêmeos digitais. Ele também descreve como executar suas consultas depois de gravá-las, usando a API de Consulta dos Gêmeos Digitais do Azure ou um SDK.

Observação

Para executar as consultas de exemplo abaixo com uma API ou chamada do SDK, você precisa condensar o texto da consulta em uma linha.

Documentação de referência

A referência de linguagem de consulta pode ser encontrada em Referência, no índice à esquerda, para a documentação dos Gêmeos Digitais do Azure. Você também pode ir diretamente para as seções de referência usando os links abaixo:

Mostrar todos os gêmeos digitais

Aqui está uma consulta básica que retorna a lista de todos os gêmeos digitais na instância:

SELECT * FROM DIGITALTWINS

Consultar por propriedade

Obter gêmeos digitais por Propriedades (incluindo a ID e os metadados):

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

Conforme mostrado na consulta acima, a ID de um gêmeo digital é consultada usando o campo de metadados $dtId.

Dica

Ao usar o Cloud Shell para executar uma consulta com campos de metadados iniciados por $, você deve escapar o $ com uma barra invertida para informar ao Cloud Shell que ele não é uma variável e deve ser consumido como um literal no texto da consulta.

Você também pode obter gêmeos com base no fato de uma determinada propriedade ser definida. Aqui está uma consulta que mostra os gêmeos que têm a propriedade Location definida:

SELECT *​ FROM DIGITALTWINS WHERE IS_DEFINED(Location)

Essa consulta ajuda a ver gêmeos pelas propriedades de tag, conforme descrito em Adicionar marcas aos gêmeos digitais. Aqui está uma consulta que mostra todos os gêmeos marcados com red:

SELECT * FROM DIGITALTWINS WHERE IS_DEFINED(tags.red)

Você também pode ver os gêmeos com base no tipo de uma propriedade. Aqui está uma consulta que mostra os gêmeos cuja propriedade de Temperature é um número:

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

Propriedades do Mapa de Consultas

Se uma propriedade for do tipo Mapcomplexo , você poderá usar as chaves e os valores do mapa diretamente na consulta, desta forma:

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

Se a chave do mapa começar com um caractere numérico, você precisará encapsular a chave em colchetes duplos ([[<mapKey>]]) para escapar dela na consulta, semelhante à estratégia de consulta com palavras-chave reservadas.

Consultar por modelo

O operador IS_OF_MODEL pode ser usado para filtrar com base no modelo do gêmeo.

Ele considera a herança e o controle de versão de modelo e é avaliado como true para um gêmeo quando o gêmeo atende a qualquer uma destas condições:

  • O gêmeo implementa diretamente o modelo fornecido ao IS_OF_MODEL(), e o número de versão do modelo no gêmeo é maior ou igual ao número de versão do modelo fornecido
  • O gêmeo implementa um modelo que estende o modelo fornecido ao IS_OF_MODEL(), e o número de versão do modelo estendido do gêmeo é maior ou igual ao número de versão do modelo fornecido

Por exemplo, se você consultar gêmeos do modelo dtmi:example:widget;4, a consulta retornará todos os gêmeos com base na versão 4 ou superior do modelo de widget e os gêmeos com base na versão 4 ou superior de modelos que herdam do widget.

O IS_OF_MODEL pode receber vários parâmetros diferentes, e o restante desta seção é dedicado às opções de sobrecarga.

O uso mais simples do IS_OF_MODEL tem apenas um parâmetro twinTypeName: IS_OF_MODEL(twinTypeName). Aqui está um exemplo de consulta que passa um valor nesse parâmetro:

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

Para especificar uma coleção de gêmeos a ser pesquisada quando há mais de uma (como quando um JOIN é usado), adicione o parâmetro twinCollection: IS_OF_MODEL(twinCollection, twinTypeName). Aqui está um exemplo de consulta que adiciona um valor para esse parâmetro:

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

Para fazer uma correspondência exata, adicione o parâmetro exact: IS_OF_MODEL(twinTypeName, exact). Aqui está um exemplo de consulta que adiciona um valor para esse parâmetro:

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

Você também pode passar todos os três argumentos juntos: IS_OF_MODEL(twinCollection, twinTypeName, exact). Aqui está um exemplo de consulta que especifica um valor para todos os três parâmetros:

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

Consultar por relação

Ao consultar com base em relacionamentos de gêmeos digitais, a linguagem de consulta dos Gêmeos Digitais do Azure tem uma sintaxe especial.

Os relacionamentos são capturados para o escopo da consulta na cláusula FROM. Ao contrário das linguagens do tipo SQL "clássico", cada expressão nessa cláusula FROM não é uma tabela. Em vez disso, a cláusula FROM expressa uma passagem de relacionamento entre entidades. Para percorrer relações, os Gêmeos Digitais do Azure usa uma versão personalizada do JOIN.

Lembre-se de que, com as funcionalidades de modelo dos Gêmeos Digitais do Azure de modelo, as relações não existem independentemente dos gêmeos, o que significa que as relações aqui não podem ser consultadas de forma independente e devem ser vinculadas a um gêmeo. Para refletir esse fato, a palavra-chave RELATED é usada na cláusula JOIN para efetua pull no conjunto de um determinado tipo de relação proveniente da coleção de gêmeos. Em seguida, a consulta deve filtrar na cláusula WHERE para indicar quais gêmeos específicos usar na consulta de relação (usando os valores $dtId dos gêmeos).

A seção a seguir mostra vários exemplos disso.

Consulta de relação básica

Veja um exemplo de consulta baseada em relação. Este snippet de código seleciona todos os gêmeos digitais com a propriedade ID de ABC e todos os gêmeos digitais com um relacionamento contains.

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

O tipo da relação (contains no exemplo acima) é indicado usando o campo de name da relação de sua definição de DTDL.

Observação

O desenvolvedor não precisa correlacionar essa JOIN a um valor de chave na cláusula WHERE, nem especificar um valor de chave embutido com a definição de JOIN. Essa correlação é calculada automaticamente pelo sistema, pois as próprias propriedades de relacionamento identificam a entidade de destino.

Consultar pela origem ou destino de uma relação

Você pode usar a estrutura de consulta da relação para identificar um gêmeo digital que seja a origem ou o destino de uma relação.

Por exemplo, você pode começar com um gêmeo de origem e seguir suas relações para encontrar os gêmeos de destino das relações. Aqui está um exemplo de uma consulta que encontra os gêmeos de destino das relações de feeds provenientes do gêmeo de origem do gêmeo.

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

Você também pode começar com o destino da relação e rastrear a relação de volta para encontrar o gêmeo de origem. Veja um exemplo de uma consulta que encontra o gêmeo de origem de uma relação de feeds com o gêmeo de destino do gêmeo.

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

Consultar as propriedades de um relacionamento

Da mesma forma que os gêmeos digitais têm propriedades descritas por meio de DTDL, os relacionamentos também podem ter propriedades. Você pode consultar gêmeos com base nas propriedades de seus relacionamentos. A linguagem de consulta dos Gêmeos Digitais do Azure permite filtrar e projetar relacionamentos atribuindo um alias à relação dentro da cláusula JOIN.

Como exemplo, considere a relação servicedBy que tem a propriedade reportedCondition. Na consulta abaixo, esse relacionamento recebe o alias R para referenciar a propriedade dele.

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

No exemplo acima, observe que reportedCondition é uma propriedade da relação servicedBy em si (NÃO de gêmeos digitais que têm uma relação de servicedBy).

Consulta com várias JOINs

Há compatibilidade com até cinco JOINs em uma única consulta, o que permite a passagem de vários níveis de relações de uma só vez.

Para consultar vários níveis de relações, use uma única instrução FROM seguida por N instruções JOIN, em que as instruções JOIN expressam relações no resultado de uma instrução FROM ou JOIN anterior.

Aqui está um exemplo de uma consulta de várias junções, que obtém todas as lâmpadas contidas nos painéis de luzes nas salas 1 e 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']

Contar itens

Você pode contar o número de itens em um conjunto de resultados usando a cláusula Select COUNT:

SELECT COUNT()
FROM DIGITALTWINS

Adicione a cláusula WHERE para contar o número de itens que atendem a um determinado critério. Aqui estão alguns exemplos de contagem com um filtro aplicado com base no tipo de modelo de gêmeo (para mais informações sobre essa sintaxe, confira Consulta por modelo abaixo):

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

Você também pode usar COUNT junto com a cláusula JOIN. Aqui está uma consulta que conta todas as lâmpadas contidas nos painéis de luzes das salas 1 e 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']

Filtrar resultados: selecionar itens principais

Você pode selecionar os vários itens "principais" em uma consulta usando a cláusula Select TOP.

SELECT TOP (5)
FROM DIGITALTWINS
WHERE ...

Filtrar resultados: especificar conjunto de retorno com projeções

Usando projeções na instrução SELECT, você pode escolher as colunas que uma consulta retornará. Agora há suporte para projeção para propriedades primitivas e complexas. Para obter mais informações sobre projeções com Gêmeos Digitais do Azure, confira a documentação de referência da cláusula SELECT.

Aqui está um exemplo de uma consulta que usa projeção para retornar gêmeos e relações. A consulta a seguir projeta o Consumidor, o Alocador e a Borda de um cenário em que um Alocador com uma ID de ABC está relacionada ao Consumidor por meio de uma relação de Factory.customer, e essa relação é apresentada como a Edge.

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

Você também pode usar projeção para retornar uma propriedade de um gêmeo. A consulta a seguir projeta a propriedade Name dos consumidores que estão relacionados à fábrica com a ID ABC por meio da relação Factory.customer.

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

Você também pode usar projeção para retornar uma propriedade de uma relação. Como no exemplo anterior, a consulta a seguir projeta a propriedade Name dos consumidores relacionados à fábrica com a ID ABC por meio da relação Factory.customer. Mas agora ela também retorna duas propriedades dessa relação, prop1 e prop2. Para isso, ele nomeia a relação como Edge e obtém as propriedades dela.

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

Você também pode usar aliases para simplificar consultas com projeção.

A consulta a seguir faz as mesmas operações que o exemplo anterior, mas cria alias dos nomes de propriedade para consumerName, first, second e 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'

Aqui está uma consulta semelhante que consulta o mesmo conjunto acima, mas projeta apenas a propriedade Consumer.name como consumerName e projeta o alocador completo como um gêmeo.

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

Criar consultas eficientes com o operador IN

Para reduzir significativamente o número de consultas necessárias, crie uma matriz de gêmeos e consulte com o operador IN.

Por exemplo, considere um cenário no qual edifícios contêm andares e os andares contêm salas. Para pesquisar salas em um edifício que estejam quentes, uma forma é seguir estas etapas.

  1. Encontre andares no prédio com base na relação contains.

    SELECT Floor
    FROM DIGITALTWINS Building
    JOIN Floor RELATED Building.contains
    WHERE Building.$dtId = @buildingId
    
  2. Para localizar salas, em vez de considerar os andares um a um e executar uma consulta JOIN para localizar as salas de cada um, você pode consultar com uma coleção dos andares no edifício (chamada andar na consulta abaixo).

    No aplicativo cliente:

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

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

Outros exemplos de consulta composta

Você pode combinar qualquer um dos tipos de consulta acima usando operadores de combinação para incluir mais detalhes em uma consulta. Aqui estão alguns outros exemplos de consultas compostas que consultam mais de um tipo de descritor de gêmeo ao mesmo tempo.

  • Dos dispositivos que a sala 123 tem, retorne os dispositivos MxChip que têm a função 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'
    
  • Obtenha gêmeos que têm uma relação chamada Contains com outro gêmeo que tem a ID id1
    SELECT Room
    FROM DIGITALTWINS Room
    JOIN Thermostat RELATED Room.Contains
    WHERE Thermostat.$dtId = 'id1'
    
  • Obter todas as salas deste modelo de sala que estão contidas por 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')
    

Executar consultas com a API

Depois de decidir sobre uma cadeia de caracteres de consulta, execute-a fazendo uma chamada para a API de consulta.

Você pode chamar a API diretamente ou usar um dos SDKs disponíveis para os Gêmeos Digitais do Azure.

O seguinte snippet de código ilustra a chamada do SDK do .NET (C#) em um aplicativo cliente:

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

A consulta usada nesta chamada retorna uma lista de gêmeos digitais, que o exemplo acima representa com objetos BasicDigitalTwin. O tipo de retorno dos dados para cada consulta depende dos termos que você especificar com a instrução SELECT:

  • As consultas que começam com SELECT * FROM ... retornam uma lista de gêmeos digitais (que podem ser serializados como objetos BasicDigitalTwin ou outros tipos de gêmeos digitais personalizados que você possa ter criado).
  • As consultas que começam no formato SELECT <A>, <B>, <C> FROM ... retornam um dicionário com chaves <A>, <B> e <C>.
  • Outros formatos de instruções SELECT podem ser criados para retornar dados personalizados. Você pode considerar a criação de classes próprias para lidar com conjuntos de resultados personalizados.

Consulta com paginação

As chamadas de consulta dão suporte para paginação. Aqui está um exemplo completo usando BasicDigitalTwin como tipo de resultado de consulta com tratamento de erro e paginação:

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

Próximas etapas

Saiba mais sobre as APIs e SDKs dos Gêmeos Digitais do Azure, incluindo a API de consulta que é usada para executar as consultas deste artigo.