IoT Hub-frågespråk för enhet och modultvillingar, jobb och meddelanderedigering

IoT Hub tillhandahåller ett kraftfullt SQL-liknande språk för att hämta information om enhetstvillingar, modultvillingar, jobb och meddelanderoutning. I den här artikeln presenteras:

  • En introduktion till de viktigaste funktionerna i IoT Hub frågespråk, och
  • Den detaljerade beskrivningen av språket. Mer information om frågespråk för meddelanderoutning finns i frågor i meddelanderoutning.

Specifika exempel finns i Frågor för enhets- och modultvillingar eller Frågor för jobb.

Anteckning

Några av de funktioner som nämns i den här artikeln, t.ex. moln till enhet-meddelanden, enhetstvillingar och enhetshantering, är bara tillgängliga på IoT Hubs standardnivå. Mer information om nivåerna basic och standard/kostnadsfri IoT Hub finns i Välja rätt IoT Hub nivå för din lösning.

Köra IoT Hub frågor

Du kan köra frågor mot din IoT-hubb direkt i Azure Portal.

  1. Logga in på Azure Portal och gå till din IoT-hubb.
  2. Välj Frågor i avsnittet Enhetshantering i navigeringsmenyn.
  3. Ange din fråga i textrutan och välj Kör fråga.

Du kan också köra frågor i dina program med hjälp av Azure IoT-tjänstens SDK:er och tjänst-API:er.

Exempel på kod som implementerar IoT Hub frågor finns i avsnittet Frågeexempel med tjänst-SDK:er.

Länkar till SDK-referenssidor och exempel finns i Azure IoT SDK:er.

Grunderna i en IoT Hub fråga

Varje IoT Hub fråga består av SELECT- och FROM-satser, med valfria WHERE- och GROUP BY-satser.

Frågor körs på en samling JSON-dokument, till exempel enhetstvillingar. FROM-satsen anger den dokumentsamling som ska itereras på (antingen enheter, devices.modules eller devices.jobs).

Sedan tillämpas filtret i WHERE-satsen. Med sammansättningar grupperas resultatet av det här steget enligt vad som anges i GROUP BY-satsen. För varje grupp genereras en rad enligt vad som anges i SELECT-satsen.

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

SELECT-satsen

SELECT-select_list-satsen <> krävs i varje IoT Hub fråga. Den anger vilka värden som hämtas från frågan. Den anger de JSON-värden som ska användas för att generera nya JSON-objekt. För varje element i den filtrerade (och eventuellt grupperade) delmängden av FROM-samlingen genererar projektionsfasen ett nytt JSON-objekt. Det här objektet konstrueras med de värden som anges i SELECT-satsen.

Exempel:

  • Returnera alla värden

    SELECT *
    
  • Returnera specifika egenskaper

    SELECT DeviceID, LastActivityTime
    
  • Aggregera resultatet av en fråga för att returnera ett antal

    SELECT COUNT() as TotalNumber
    

För närvarande stöds markeringssatser som skiljer sig från SELECT endast i aggregerade frågor på enhetstvillingar.

Följande syntax är grammatiken i SELECT-satsen:

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 refererar till alla egenskaper för JSON-dokumentet i FROM-samlingen.

FROM-satsen

FROM-from_specification-satsen <> krävs i varje ioT Hub-fråga. Det måste vara ett av tre värden:

  • enheter för att fråga enhetstvillingar
  • devices.modules för att fråga modultvillingar
  • devices.jobs för att fråga efter jobbinformation per enhet

Exempel:

  • Hämta alla enhetstvillingar

    SELECT * FROM devices
    

WHERE-satsen

WHERE-filter_condition-satsen <> är valfri. Den anger ett eller flera villkor som JSON-dokumenten i FROM-samlingen måste uppfylla för att inkluderas som en del av resultatet. Alla JSON-dokument måste utvärdera de angivna villkoren till "true" för att inkluderas i resultatet.

Exempel:

  • Hämta alla jobb som riktar sig till en specifik enhet

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

De tillåtna villkoren beskrivs i avsnittet uttryck och villkor .

GROUP BY-sats

Satsen GROUP BY <group_specification> är valfri. Den här satsen körs efter det filter som anges i WHERE-satsen och före projektionen som anges i SELECT. Den grupperar dokument baserat på värdet för ett attribut. Dessa grupper används för att generera aggregerade värden enligt vad som anges i SELECT-satsen.

Exempel:

  • Returnera antalet enheter som rapporterar varje telemetrikonfigurationsstatus

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

För närvarande stöds GROUP BY-satsen endast när du frågar enhetstvillingar.

Varning

Termen group behandlas för närvarande som ett särskilt nyckelord i frågor. Om du använder group som egenskapsnamn bör du överväga att omge den med dubbla hakparenteser för att undvika fel, t.ex. SELECT * FROM devices WHERE tags.[[group]].name = 'some_value'.

Den formella syntaxen för GROUP BY är:

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

Attribute_name refererar till alla egenskaper för JSON-dokumentet i FROM-samlingen.

Sidnumrering av frågeresultat

Ett frågeobjekt instansieras med en maximal sidstorlek på mindre än eller lika med 100 poster. Om du vill hämta flera sidor anropar du metoden nextAsTwin på Node.js SDK eller GetNextAsTwinAsync på .Net SDK flera gånger. Ett frågeobjekt kan exponera flera Nästa-värden, beroende på vilket deserialiseringsalternativ som krävs av frågan. Ett frågeobjekt kan till exempel returnera enhetstvilling- eller jobbobjekt, eller oformaterad JSON när projektioner används.

Uttryck och villkor

På en hög nivå, ett uttryck:

  • Utvärderas till en instans av en JSON-typ (till exempel boolesk, siffra, sträng, matris eller objekt).
  • Definieras genom att manipulera data som kommer från enhetens JSON-dokument och konstanter med hjälp av inbyggda operatorer och funktioner.

Villkor är uttryck som utvärderas till ett booleskt värde. Alla konstanter som skiljer sig från boolesk true anses vara false. Den här regeln innehåller null, odefinierad, alla objekt- eller matrisinstanser, valfri sträng och det booleska värdet false.

Syntaxen för uttryck är:

<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>]+ ']'

Information om vad varje symbol i uttryckssyntaxen står för finns i följande tabell:

Symbol Definition
attribute_name Alla egenskaper för JSON-dokumentet i FROM-samlingen .
binary_operator Valfri binär operator som anges i avsnittet Operatorer .
function_name Alla funktioner som anges i avsnittet Funktioner .
decimal_literal Ett flyttal uttryckt i decimalnotation.
hexadecimal_literal Ett tal som uttrycks av strängen "0x" följt av en sträng med hexadecimala siffror.
string_literal Unicode-strängar som representeras av en sekvens med noll eller fler Unicode-tecken eller escape-sekvenser. Strängliteraler omges av enkla citattecken eller dubbla citattecken. Tillåtna escapes: \', \", \\, \uXXXX för Unicode-tecken som definieras av fyra hexadecimala siffror.

Operatorer

Följande operatorer stöds:

Familj Operatorer
Aritmetisk +, -, *, /, %
Logiskt AND, OR, NOT (och, eller, inte)
Jämförelse =, !=, <, >, <=, >=, <>

Functions

När du kör frågor mot tvillingar och jobb är den enda funktion som stöds:

Funktion Beskrivning
IS_DEFINED(egenskap) Returnerar ett booleskt värde som anger om egenskapen har tilldelats ett värde (inklusive null).

I vägförhållanden stöds följande matematiska funktioner:

Funktion Beskrivning
ABS(x) Returnerar det absoluta (positiva) värdet för det angivna numeriska uttrycket.
EXP(x) Returnerar det exponentiella värdet för det angivna numeriska uttrycket (e^x).
POWER(x,y) Returnerar värdet för det angivna uttrycket till den angivna kraften (x^y).
SQUARE(x) Returnerar kvadraten för det angivna numeriska värdet.
CEILING(x) Returnerar det minsta heltalsvärdet som är större än eller lika med det angivna numeriska uttrycket.
FLOOR(x) Returnerar det största heltalsvärdet som är mindre än eller lika med det angivna numeriska uttrycket.
SIGN(x) Returnerar det positiva (+1), noll (0) eller negativa (-1) tecknet för det angivna numeriska uttrycket.
SQRT(x) Returnerar kvadratroten för det angivna numeriska värdet.

I routningsvillkor stöds följande typkontroll- och omvandlingsfunktioner:

Funktion Beskrivning
AS_NUMBER Konverterar indatasträngen till ett tal. noop om indata är ett tal; Undefined om strängen inte representerar ett tal.
IS_ARRAY Returnerar ett booleskt värde som anger om typen av det angivna uttrycket är en matris.
IS_BOOL Returnerar ett booleskt värde som anger om typen av det angivna uttrycket är boolesk.
IS_DEFINED Returnerar ett booleskt värde som anger huruvida egenskapen har tilldelats ett värde. Den här funktionen stöds bara när värdet är en primitiv typ. Primitiva typer är sträng, boolesk, numerisk eller null. DateTime, objekttyper och matriser stöds inte.
IS_NULL Returnerar ett booleskt värde som anger om typen av det angivna uttrycket är null.
IS_NUMBER Returnerar ett booleskt värde som anger om typen av det angivna uttrycket är ett tal.
IS_OBJECT Returnerar ett booleskt värde som anger om typen av det angivna uttrycket är ett JSON-objekt.
IS_PRIMITIVE Returnerar ett booleskt värde som anger om typen av det angivna uttrycket är en primitiv (sträng, boolesk, numerisk eller null).
IS_STRING Returnerar ett booleskt värde som anger om typen av det angivna uttrycket är en sträng.

I routningsvillkor stöds följande strängfunktioner:

Funktion Beskrivning
CONCAT(x, y, ...) Returnerar en sträng som är resultatet av en sammanfogning av två eller fler strängvärden.
LENGTH(x) Returnerar antalet tecken i det angivna stränguttrycket.
LOWER(x) Returnerar ett stränguttryck efter att teckendata med versaler har konverterats till gemener.
UPPER(x) Returnerar ett stränguttryck efter att teckendata med gemener har konverterats till versaler.
SUBSTRING(string, start [, length]) Returnerar en del av ett stränguttryck med början vid det angivna tecknet nollbaserad position och fortsätter till den angivna längden eller till slutet av strängen.
INDEX_OF(sträng, fragment) Returnerar startpositionen för den första förekomsten av det andra stränguttrycket i det första angivna stränguttrycket, eller -1 om strängen inte hittas.
STARTSWITH(x, y) Returnerar ett booleskt värde som anger om det första stränguttrycket börjar med det andra.
ENDSWITH(x, y) Returnerar ett booleskt värde som anger om det första stränguttrycket slutar med det andra.
CONTAINS(x,y) Returnerar ett booleskt värde som anger huruvida det första stränguttrycket innehåller det andra.

Frågeexempel med tjänst-SDK:er

C#-exempel

Frågefunktionen exponeras av C#-tjänst-SDK :t i klassen RegistryManager .

Här är ett exempel på en enkel fråga:

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

Frågeobjektet instansieras med parametrarna som anges i sidnumreringsavsnittet för frågeresultat . Flera sidor hämtas genom att anropa GetNextAsTwinAsync-metoderna flera gånger.

Node.js exempel

Frågefunktionen exponeras av Azure IoT-tjänst-SDK:t för Node.js i Registry-objektet .

Här är ett exempel på en enkel fråga:

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

Frågeobjektet instansieras med parametrarna som anges i sidnumreringsavsnittet för frågeresultat . Flera sidor hämtas genom att metoden nextAsTwin anropas flera gånger.

Nästa steg