Linguaggio di query dell'hub IoT per dispositivi e moduli gemelli, processi e routing di messaggi

hub IoT offre un linguaggio sql potente per recuperare informazioni relative ai dispositivi gemelli, ai moduli gemelli, ai processi e al routing dei messaggi. Questo articolo contiene:

  • Un'introduzione alle principali funzionalità del linguaggio di query dell'hub IoT
  • La descrizione dettagliata del linguaggio Per informazioni sul linguaggio di query per il routing dei messaggi, vedere Query nel routing dei messaggi.

Per esempi specifici, vedere Query per dispositivi e moduli gemelli o query per i processi.

Nota

Alcune delle funzionalità indicate in questo articolo, come la messaggistica da cloud a dispositivo, i dispositivi gemelli e la gestione dei dispositivi, sono disponibili solo nel livello Standard dell'hub IoT. Per altre informazioni sui livelli di hub IoT di base e standard/gratuiti, vedere Scegliere il livello di hub IoT appropriato per la soluzione.

Eseguire query hub IoT

È possibile eseguire query sull'hub IoT direttamente nell'portale di Azure.

  1. Accedere al portale di Azure e passare all'hub IoT.
  2. Selezionare Query nella sezione Gestione dispositivi del menu di spostamento.
  3. Immettere la query nella casella di testo e selezionare Esegui query.

È anche possibile eseguire query all'interno delle applicazioni usando gli SDK e le API del servizio IoT di Azure.

Ad esempio, il codice che implementa hub IoT query, vedere la sezione Esempi di query con gli SDK del servizio.

Per i collegamenti alle pagine di riferimento e agli esempi sdk, vedere Sdk IoT di Azure.

Nozioni di base di una query dell'hub IoT

Ogni query dell'hub IoT è costituita da una clausola SELECT e da una clausola FROM e dalle clausole facoltative WHERE e GROUP BY.

Le query vengono eseguite in una raccolta di documenti JSON, ad esempio dispositivi gemelli. La clausola FROM indica l'iterazione della raccolta documenti in (dispositivi, dispositivi.modules o devices.jobs).

Viene quindi applicato il filtro nella clausola WHERE. Con le aggregazioni, i risultati di questo passaggio vengono raggruppati come specificato nella clausola GROUP BY. Per ogni gruppo, viene generata una riga come specificato nella clausola SELECT.

SELECT <select_list>
  FROM <from_specification>
  [WHERE <filter_condition>]
  [GROUP BY <group_specification>]

Clausola SELECT

La clausola SELECT <select_list> è necessaria in ogni query hub IoT. Specifica i valori recuperati dalla query. Specifica i valori JSON da usare per generare nuovi oggetti JSON. Per ogni elemento del subset filtrato (e facoltativamente raggruppato) della raccolta FROM, la fase di proiezione genera un nuovo oggetto JSON, costruito con i valori specificati nella clausola SELECT.

Ad esempio:

  • Restituisce tutti i valori

    SELECT *
    
  • Restituire proprietà specifiche

    SELECT DeviceID, LastActivityTime
    
  • Aggregare i risultati di una query per restituire un conteggio

    SELECT COUNT() as TotalNumber
    

Attualmente, le clausole di selezione diverse da SELECT sono supportate solo nelle query di aggregazione nei dispositivi gemelli.

La sintassi seguente è la grammatica della clausola SELECT:

SELECT [TOP <max number>] <projection list>

<projection_list> ::=
    '*'
    | <projection_element> AS alias [, <projection_element> AS alias]+

<projection_element> :==
    attribute_name
    | <projection_element> '.' attribute_name
    | <aggregate>

<aggregate> :==
    count()
    | avg(<projection_element>)
    | sum(<projection_element>)
    | min(<projection_element>)
    | max(<projection_element>)

Attribute_name si riferisce alle proprietà del documento JSON nella raccolta FROM.

Clausola FROM

La clausola FROM <from_specification> è necessaria in ogni query dell'hub ioT. Deve essere uno dei tre valori:

  • dispositivi per eseguire query sui dispositivi gemelli
  • devices.modules per eseguire query sui moduli gemelli
  • devices.jobs per eseguire query sui dettagli del processo per dispositivo

Ad esempio:

  • Recuperare tutti i dispositivi gemelli

    SELECT * FROM devices
    

WHERE - clausola

La clausola WHERE <filter_condition> è facoltativa. e specifica una o più condizioni che i documenti JSON della raccolta FROM devono soddisfare per essere inclusi come parte del risultato. Per essere incluso nel risultato, qualsiasi documento JSON deve restituire "true" per le condizioni specificate.

Ad esempio:

  • Recuperare tutti i processi destinati a un dispositivo specifico

    SELECT * FROM devices.jobs
      WHERE devices.jobs.deviceId = 'myDeviceId'
    

Le condizioni consentite sono descritte nella sezione espressioni e condizioni .

Clausola GROUP BY

La clausola GROUP BY <group_specification> è facoltativa. Questa clausola viene eseguita dopo il filtro specificato nella clausola WHERE e prima della proiezione specificata in SELECT. Raggruppa i documenti in base al valore di un attributo. Questi gruppi vengono usati per generare valori aggregati come specificato nella clausola SELECT.

Ad esempio:

  • Restituisce il numero di dispositivi che segnalano ogni stato di configurazione della telemetria

    SELECT properties.reported.telemetryConfig.status AS status,
      COUNT() AS numberOfDevices
    FROM devices
    GROUP BY properties.reported.telemetryConfig.status
    

Attualmente la clausola GROUP BY è supportata solo quando si effettua una query sui dispositivi gemelli.

Attenzione

Il termine group viene attualmente considerato una parola chiave speciale nelle query. Se si utilizza group come nome di proprietà, è consigliabile racchiuderlo tra doppie parentesi quadre per evitare errori, ad esempio SELECT * FROM devices WHERE tags.[[group]].name = 'some_value'.

La sintassi formale di GROUP BY è:

GROUP BY <group_by_element>
<group_by_element> :==
    attribute_name
    | < group_by_element > '.' attribute_name

Attribute_name si riferisce alle proprietà del documento JSON nella raccolta FROM.

Paginazione dei risultati delle query

Un oggetto query viene creato un'istanza con dimensioni massime di pagina inferiori o uguali a 100 record. Per ottenere più pagine, chiamare il metodo nextAsTwin in Node.js SDK o GetNextAsTwinAsync in .Net SDK più volte. Un oggetto query può esporre più valori Next, a seconda dell'opzione di deserializzazione richiesta dalla query. Ad esempio, un oggetto query può restituire oggetti gemelli o processi o JSON normale quando si usano proiezioni.

Espressioni e condizioni

In generale, un'espressione:

  • Restituisce un'istanza di un tipo JSON, ad esempio un operatore booleano, un numero, una stringa, una matrice o un oggetto.
  • Viene definita modificando i dati provenienti dalle costanti e dal documento JSON dei dispositivi, che usano funzioni e operatori predefiniti.

Le condizioni sono espressioni che restituiscono un valore booleano. Qualsiasi costante diversa dal valore booleano true viene considerata come false. Questa regola include null, undefined, qualsiasi istanza di oggetto o di matrice, qualsiasi stringa e il valore booleano false.

La sintassi delle espressioni è:

<expression> ::=
    <constant> |
    attribute_name |
    <function_call> |
    <expression> binary_operator <expression> |
    <create_array_expression> |
    '(' <expression> ')'

<function_call> ::=
    <function_name> '(' expression ')'

<constant> ::=
    <undefined_constant>
    | <null_constant>
    | <number_constant>
    | <string_constant>
    | <array_constant>

<undefined_constant> ::= undefined
<null_constant> ::= null
<number_constant> ::= decimal_literal | hexadecimal_literal
<string_constant> ::= string_literal
<array_constant> ::= '[' <constant> [, <constant>]+ ']'

Per informazioni sul significato di ogni simbolo nella sintassi delle espressioni, fare riferimento alla tabella seguente:

Simbolo Definizione
attribute_name Proprietà del documento JSON nella raccolta FROM.
binary_operator Operatore binario elencato nella sezione Operatori.
function_name Funzioni elencate nella sezione Funzioni.
decimal_literal Float espresso in una notazione decimale.
hexadecimal_literal Numero espresso dalla stringa '0x' seguita da una stringa di cifre esadecimali.
string_literal Stringhe Unicode rappresentate da una sequenza di zero o più caratteri Unicode o sequenze di escape. I valori letterali stringa sono racchiusi tra virgolette singole o virgolette doppie. Escape consentiti: \', \", \\\uXXXX per i caratteri Unicode definiti da quattro cifre esadecimali.

Operatori

Sono supportati gli operatori seguenti:

Famiglia Operatori
Aritmetico +, -, *, /, %
Logico AND, OR, NOT
Confronto =, !=, <, >, <=, >=, <>

Funzioni

Quando si eseguono query gemelle e di processi l'unica funzione supportata è:

Funzione Descrizione
IS_DEFINED(proprietà) Restituisce un valore booleano che indica se alla proprietà è stata assegnato un valore (incluso null).

Nelle condizioni di route, sono supportate le funzioni matematiche seguenti:

Funzione Descrizione
ABS(x) Restituisce il valore assoluto (positivo) dell'espressione numerica specificata.
EXP(x) Restituisce il valore esponente dell'espressione numerica specificata (e^x).
POWER(x,y) Restituisce il valore dell'espressione specificata alla potenza specificata (x^y).
SQUARE(x) Restituisce il quadrato del valore numerico specificato.
CEILING(x) Restituisce il più piccolo valore integer maggiore di o uguale all'espressione numerica specificata.
FLOOR(x) Restituisce l'intero maggiore che risulta minore o uguale all'espressione numerica specificata.
SIGN(x) Restituisce il segno positivo (+1), zero (0) o negativo (-1) dell'espressione numerica specificata.
SQRT(x) Restituisce la radice quadrata del valore numerico specificato.

Nelle condizioni di route, sono supportate le funzioni di trasmissione e controllo seguenti:

Funzione Descrizione
AS_NUMBER Converte la stringa di input in un numero. noop se l'input è un numero; Undefined se la stringa non rappresenta un numero.
IS_ARRAY Restituisce un valore booleano che indica se il tipo di espressione specificata è una matrice.
IS_BOOL Restituisce un valore booleano che indica se il tipo di espressione specificata è un valore booleano.
IS_DEFINED Restituisce un valore booleano che indica se alla proprietà è stata assegnato un valore. Questa funzione è supportata solo quando il valore è un tipo primitivo. I tipi primitivi includono stringhe, booleane, numeriche o null. DateTime, tipi di oggetti e matrici non sono supportati.
IS_NULL Restituisce un valore booleano che indica se il tipo di espressione specificata è nulla.
IS_NUMBER Restituisce un valore booleano che indica se il tipo di espressione specificata è un numero.
IS_OBJECT Restituisce un valore booleano che indica se il tipo di espressione specificata è un oggetto JSON.
IS_PRIMITIVE Restituisce un valore booleano che indica se il tipo dell'espressione specificata è primitivo (stringa, valore booleano, numerico o null).
IS_STRING Restituisce un valore booleano che indica se il tipo di espressione specificata è una stringa.

Nelle condizioni di route, sono supportate le funzioni di stringa seguenti:

Funzione Descrizione
CONCAT(x, y, …) Restituisce una stringa che rappresenta il risultato della concatenazione di due o più valori di stringa.
LENGTH(x) Restituisce il numero di caratteri dell'espressione stringa specificata.
LOWER(x) Restituisce un'espressione stringa dopo la conversione di dati in caratteri maiuscoli in caratteri minuscoli.
UPPER(x) Restituisce un'espressione stringa dopo aver convertito i caratteri minuscoli in caratteri maiuscoli.
SUBSTRING (stringa, avvio [, lunghezza]) Restituisce parte di un'espressione stringa a partire dalla posizione in base al carattere zero specificata e continua fino alla lunghezza specificata o alla fine della stringa.
INDEX_OF(stringa, frammento) Restituisce la posizione iniziale della prima occorrenza della seconda espressione stringa all'interno della prima espressione stringa specificata oppure -1 se la stringa non viene trovata.
STARTSWITH(x, y) Restituisce un valore booleano che indica se la prima espressione stringa inizia con il secondo.
ENDWITH(x, y) Restituisce un valore booleano che indica se la prima espressione stringa termina con il secondo.
CONTAINS(x,y) Restituisce un valore booleano che indica se la prima espressione stringa contiene il secondo.

Esempi di query con gli SDK del servizio

Esempio in C#

La funzionalità di query viene esposta dall'SDK del servizio C# nella classe RegistryManager.

Ecco un esempio di una semplice query:

var query = registryManager.CreateQuery("SELECT * FROM devices", 100);
while (query.HasMoreResults)
{
    var page = await query.GetNextAsTwinAsync();
    foreach (var twin in page)
    {
        // do work on twin object
    }
}

L'oggetto query viene creata un'istanza con i parametri menzionati nella sezione paginazione dei risultati della query . Più pagine vengono recuperate chiamando i metodi GetNextAsTwinAsync più volte.

Esempio di Node. js

La funzionalità di query viene esposta da SDK per i servizi IoT di Azure per Node.js nell'oggetto Registro.

Ecco un esempio di una semplice query:

var query = registry.createQuery('SELECT * FROM devices', 100);
var onResults = function(err, results) {
    if (err) {
        console.error('Failed to fetch the results: ' + err.message);
    } else {
        // Do something with the results
        results.forEach(function(twin) {
            console.log(twin.deviceId);
        });

        if (query.hasMoreResults) {
            query.nextAsTwin(onResults);
        }
    }
};
query.nextAsTwin(onResults);

L'oggetto query viene creata un'istanza con i parametri menzionati nella sezione paginazione dei risultati della query . Più pagine vengono recuperate chiamando il metodo nextAsTwin più volte.

Passaggi successivi