IoT Hub-Abfragesprache für Geräte- und Modulzwillinge, Aufträge und Nachrichtenrouting
IoT Hub verfügt über eine leistungsstarke SQL-ähnliche Sprache zum Abrufen von Informationen zu Gerätezwillingen, Modulzwillingen, Aufträgen und zum Nachrichtenrouting. Dieser Artikel enthält Folgendes:
- Eine Einführung in die wichtigsten Features der IoT Hub-Abfragesprache
- Eine ausführliche Beschreibung der Sprache Weitere Informationen zur Abfragesprache für das Nachrichtenrouting finden Sie unter Abfragen im Nachrichtenrouting.
Konkrete Beispiele finden Sie unter Abfragen für Geräte- und Modulzwillinge oder Abfragen für Aufträge.
Hinweis
Einige der in diesem Artikel erwähnten Features (wie Cloud-zu-Gerät-Messaging, Gerätezwillinge und Geräteverwaltung) stehen nur im Standard-Tarif von IoT Hub zur Verfügung. Weitere Informationen zu den IoT Hub-Tarifen „Basic“ und „Standard/Free“ finden Sie unter Wählen des richtigen IoT Hub-Tarifs für Ihre Lösung.
Ausführen IoT Hub-Abfragen
Sie können Abfragen für Ihren IoT-Hub direkt im Azure-Portal ausführen.
- Melden Sie sich beim Azure-Portal an, und navigieren Sie zu Ihrem IoT Hub.
- Wählen Sie Abfragen im Abschnitt Geräteverwaltung des Navigationsmenüs aus.
- Geben Sie eine Abfrage in das Textfeld ein und wählen Sie Abfrage ausführen aus.
Sie können auch Abfragen in Ihren Anwendungen mit den Azure IoT-Dienst-SDKs und Dienst-APIs ausführen.
Beispielcode zur Implementierung von IoT Hub-Abfragen finden Sie im Abschnitt Abfragebeispiele mit den Dienst-SDKs.
Links zu SDK-Referenzseiten und Beispielen finden Sie unter Azure IoT SDKs.
Grundlagen von IoT Hub-Abfragen
Jede IoT Hub-Abfrage besteht aus einer SELECT- und einer FROM-Klausel mit optionalen WHERE- und GROUP BY-Klauseln.
Abfragen werden für eine Sammlung von JSON-Dokumenten ausgeführt, z. B. Gerätezwillinge. Die FROM-Klausel zeigt die Dokumentsammlung an, die durchlaufen werden soll (entweder devices, devices.modules oder devices.jobs).
Anschließend wird der Filter in der WHERE-Klausel angewendet. Mit Aggregationen werden die Ergebnisse dieses Schritts gruppiert, wie in der GROUP BY-Klausel angegeben. Für jede Gruppe wird eine Zeile generiert, wie in der SELECT-Klausel angegeben.
SELECT <select_list>
FROM <from_specification>
[WHERE <filter_condition>]
[GROUP BY <group_specification>]
SELECT-Klausel
Die Klausel SELECT <select_list> ist in jeder IoT Hub-Abfrage erforderlich. Sie gibt an, welche Werte von der Abfrage abgerufen werden. Sie gibt die JSON-Werte an, mit denen die neuen JSON-Objekte erstellt werden sollen. Für jedes Element der gefilterten (und optional gruppierten) Teilmenge der FROM-Sammlung wird in der Projektionsphase ein neues JSON-Objekt generiert. Dieses Objekt wird mit den in der SELECT-Klausel angegebenen Werten erstellt.
Beispiel:
Rückgabe aller Werte
SELECT *
Rückgabe spezifischer Eigenschaften
SELECT DeviceID, LastActivityTime
Aggregieren der Ergebnisse einer Abfrage, um eine Anzahl zurückzugeben
SELECT COUNT() as TotalNumber
Derzeit werden andere Auswahlklauseln als SELECT nur in Aggregatabfragen für Gerätezwillinge unterstützt.
Die folgende Syntax ist die Grammatik der SELECT-Klausel:
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 bezieht sich auf jede Eigenschaft des JSON-Dokuments in der FROM-Sammlung.
FROM-Klausel
Die Klausel FROM <from_specification> in jeder IoT Hub-Abfrage erforderlich. Dies muss einer von drei Werten sein:
- devices zum Abfragen von Gerätezwillingen
- devices.modules zum Abfragen von Modulzwillingen
- devices.jobs zum Abfragen von Auftragsdetails pro Gerät
Beispiel:
Abrufen aller Gerätezwillinge
SELECT * FROM devices
WHERE-Klausel
Die Klausel WHERE <filter_condition> ist optional. Sie gibt eine oder mehrere Bedingungen an, die von den in der FROM-Sammlung enthaltenen JSON-Dokumenten erfüllt werden müssen, um als Teil des Ergebnisses zurückgegeben zu werden. Jedes JSON-Dokument muss die angegebenen Bedingungen erfüllen, um in das Ergebnis einbezogen zu werden.
Beispiel:
Abrufen aller Aufträge, die auf ein bestimmtes Gerät abzielen
SELECT * FROM devices.jobs WHERE devices.jobs.deviceId = 'myDeviceId'
Die zulässigen Bedingungen sind im Abschnitt Ausdrücke und Bedingungen beschrieben.
GROUP BY-Klausel
Die Klausel GROUP BY <group_specification> ist optional. Diese Klausel wird nach dem in der WHERE-Klausel angegebenen Filter und vor der in SELECT angegebenen Projektion ausgeführt. Sie gruppiert Dokumente anhand des Werts eines Attributs. Diese Gruppen werden verwendet, um aggregierte Werte gemäß der SELECT-Klausel zu generieren.
Beispiel:
Zurückgeben der Anzahl der Geräte, die jeden Status für die Telemetriekonfiguration melden
SELECT properties.reported.telemetryConfig.status AS status, COUNT() AS numberOfDevices FROM devices GROUP BY properties.reported.telemetryConfig.status
Die GROUP BY-Klausel wird derzeit nur für Abfragen von Gerätezwillingen unterstützt.
Achtung
Der Begriff group
wird derzeit in Abfragen als spezielles Schlüsselwort behandelt. Wenn Sie group
als Eigenschaftenname verwenden, sollten Sie ihn zur Vermeidung von Fehlern in doppelte Klammern einschließen, z.B. SELECT * FROM devices WHERE tags.[[group]].name = 'some_value'
.
Die formale Syntax für GROUP BY lautet:
GROUP BY <group_by_element>
<group_by_element> :==
attribute_name
| < group_by_element > '.' attribute_name
Attribute_name bezieht sich auf jede Eigenschaft des JSON-Dokuments in der FROM-Sammlung.
Paginierung von Abfrageergebnissen
Ein Abfrageobjekt wird mit einer maximalen Seitengröße von kleiner als oder gleich 100 Datensätzen instanziiert. Um mehrere Seiten abzurufen, rufen Sie mehrmals die Methode nextAsTwin für das Node.js SDK oder GetNextAsTwinAsync für das .NET SDK auf. Ein Abfrageobjekt kann mehrere Next-Werte verfügbar machen, abhängig von der Deserialisierungsoption, die von der Abfrage benötigt wird. Ein Abfrageobjekt kann beispielsweise Gerätezwillings- bzw. Auftragsobjekte oder einfachen JSON-Text bei der Verwendung von Projektionen zurückgeben.
Ausdrücke und Bedingungen
Auf hoher Ebene wird ein Ausdruck:
- in eine Instanz eines JSON-Typs (z. B. boolescher Wert, Zahl, Zeichenfolge, Array oder Objekt) ausgewertet.
- durch das Ändern von Daten aus dem JSON-Dokument des Geräts und Konstanten mit integrierten Operatoren und Funktionen definiert.
Bedingungen sind Ausdrücke, die als boolescher Wert ausgewertet werden. Jede Konstante, die sich vom booleschen Ausdruck true unterscheidet, wird als false betrachtet. Diese Regel umfasst null, undefined, jede Objekt- oder Arrayinstanz, jede Zeichenfolge und den booleschen Ausdruck false.
Die Syntax für Ausdrücke lautet:
<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>]+ ']'
Informationen dazu, wofür die einzelnen Symbole in der Ausdruckssyntax stehen, finden Sie in der folgenden Tabelle:
Symbol | Definition |
---|---|
attribute_name | Eine beliebige Eigenschaft des JSON-Dokuments in der FROM-Sammlung. |
binary_operator | Ein beliebiger binärer, im Abschnitt Operatoren aufgelisteter Operator. |
function_name | Eine beliebige im Abschnitt Funktionen aufgelistete Funktion. |
decimal_literal | Ein Gleitkommawert, ausgedrückt in Dezimalschreibweise. |
hexadecimal_literal | Eine Zahl, ausgedrückt durch die Zeichenfolge „0x“ gefolgt von einer Zeichenfolge von Hexadezimalzahlen. |
string_literal | Unicode-Zeichenfolgen, die durch eine Sequenz aus null oder mehr Unicode-Zeichen oder Escapesequenzen dargestellt werden. Zeichenfolgenliterale werden in einfache Anführungszeichen oder doppelte Anführungszeichen eingeschlossen. Zulässige Escapezeichen: \' , \" , \\ , \uXXXX für Unicode-Zeichen, die durch vier Hexadezimalstellen definiert werden. |
Operatoren
Die folgenden Operatoren werden unterstützt:
Familie | Operatoren |
---|---|
Arithmetik | +, -, *, /, % |
Logisch | AND, OR, NOT |
Vergleich | =, !=, <, >, <=, >=, <> |
Functions
Bei Abfragen von Zwillingen und Aufträgen wird nur folgende Funktion unterstützt:
Funktion | BESCHREIBUNG |
---|---|
IS_DEFINED(Eigenschaft) | Gibt einen booleschen Wert zurück, um anzugeben, ob der Eigenschaft ein Wert zugewiesen wurde (inklusive null ). |
In Routenbedingungen werden die folgenden mathematischen Funktionen unterstützt:
Funktion | BESCHREIBUNG |
---|---|
ABS(x) | Gibt den absoluten (positiven) Wert des angegebenen numerischen Ausdrucks zurück. |
EXP(x) | Gibt den Exponentialwert des angegebenen numerischen Ausdrucks (e^x) zurück. |
POWER(x,y) | Gibt den Wert des angegebenen Ausdrucks gemäß der angegebenen Potenz (x^y) zurück. |
SQUARE(x) | Gibt die Quadratwurzel des angegebenen numerischen Werts zurück. |
CEILING(x) | Gibt den kleinsten ganzzahligen Wert zurück, der größer oder gleich dem angegebenen numerischen Ausdruck ist. |
FLOOR(x) | Gibt die größte ganze Zahl zurück, die kleiner oder gleich dem angegebenen numerischen Ausdruck ist. |
SIGN(x) | Gibt das positive Vorzeichen (+1), null (0) oder das negative Vorzeichen (-1) des angegebenen numerischen Ausdrucks zurück. |
SQRT(x) | Gibt die Quadratwurzel des angegebenen numerischen Werts zurück. |
In Routenbedingungen werden die folgenden Typüberprüfungs- und Umwandlungsfunktionen unterstützt:
Funktion | BESCHREIBUNG |
---|---|
AS_NUMBER | Konvertiert die Eingabezeichenfolge in eine Zahl. noop , wenn die Eingabe eine Zahl ist; Undefined , wenn die Zeichenfolge keine Zahl darstellt. |
IS_ARRAY | Gibt einen booleschen Wert zurück, der angibt, ob der angegebene Ausdruck vom Typ „Array“ ist. |
IS_BOOL | Gibt einen booleschen Wert zurück, der angibt, ob der angegebene Ausdruck vom Typ „boolesch“ ist. |
IS_DEFINED | Gibt einen booleschen Wert zurück, um anzugeben, ob der Eigenschaft ein Wert zugewiesen wurde. Diese Funktion wird nur unterstützt, wenn es sich bei dem Wert um einen primitiven Typ handelt. Primitive Typen umfassen Zeichenfolgen, boolesche Werte, numerische Werte und null . DateTime, Objekttypen und Arrays werden nicht unterstützt. |
IS_NULL | Gibt einen booleschen Wert zurück, der angibt, ob der angegebene Ausdruck vom Typ „NULL“ ist. |
IS_NUMBER | Gibt einen booleschen Wert zurück, der angibt, ob der angegebene Ausdruck vom Typ „Zahl“ ist. |
IS_OBJECT | Gibt einen booleschen Wert zurück, der angibt, ob der angegebene Ausdruck vom Typ „JSON-Objekt“ ist. |
IS_PRIMITIVE | Gibt einen booleschen Wert zurück, der angibt, ob der angegebene Ausdruck ein Grundtyp ist (Zeichenfolge, boolesch, numerisch oder null ). |
IS_STRING | Gibt einen booleschen Wert zurück, der angibt, ob der angegebene Ausdruck vom Typ „Zeichenfolge“ ist. |
In Routenbedingungen werden die folgenden Zeichenfolgenfunktionen unterstützt:
Funktion | BESCHREIBUNG |
---|---|
CONCAT(x, y, …) | Gibt eine Zeichenfolge zurück, die das Ergebnis der Verkettung von zwei oder mehr Zeichenfolgenwerten darstellt. |
LENGTH(x) | Gibt die Anzahl der Zeichen im angegebenen Zeichenfolgenausdruck zurück. |
LOWER(x) | Gibt eine Zeichenfolge zurück, nachdem Großbuchstaben in Kleinbuchstaben konvertiert wurden. |
UPPER(x) | Gibt eine Zeichenfolge zurück, nachdem Kleinbuchstaben in Großbuchstaben konvertiert wurden. |
SUBSTRING(Zeichenfolge, Start [, Länge]) | Gibt einen Teil eines Zeichenfolgenausdrucks zurück. Das angegebene Zeichen ist der Nullpunkt, von dem ab die Teilzeichenfolge in angegebener Länge bzw. bis zum Ende der Zeichenfolge zurückgegeben wird. |
INDEX_OF(Zeichenfolge, Fragment) | Gibt die Anfangsposition des ersten Vorkommens des zweiten Zeichenfolgenausdrucks innerhalb des ersten angegebenen Zeichenfolgenausdrucks zurück, oder -1, wenn die Zeichenfolge nicht gefunden wird. |
STARTSWITH(x, y) | Gibt einen booleschen Wert zurück, um anzugeben, ob der erste Zeichenfolgenausdruck mit dem zweiten beginnt. |
ENDSWITH(x, y) | Gibt einen booleschen Wert zurück, um anzugeben, ob der erste Zeichenfolgenausdruck mit dem zweiten endet. |
CONTAINS(x,y) | Gibt einen booleschen Wert zurück, um anzugeben, ob der erste Zeichenfolgenausdruck den zweiten enthält. |
Abfragebeispiele mit den Dienst-SDKs
C#-Beispiel
Die Abfragefunktion wird durch das C#-Dienst-SDK in der RegistryManager-Klasse verfügbar gemacht.
Hier ein Beispiel einer einfachen Abfrage:
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
}
}
Das Abfrageobjekt wird mit den Parametern instanziiert, die im Abschnitt Paginierung von Abfrageergebnissen erwähnt werden. Mehrere Seiten werden durch mehrmaliges Aufrufen der GetNextAsTwinAsync-Methoden aufgerufen.
Node.js-Beispiel
Die Abfragefunktion wird durch das Azure IoT-Dienst-SDK für Node.js im Registry-Objekt verfügbar gemacht.
Hier ein Beispiel einer einfachen Abfrage:
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);
Das Abfrageobjekt wird mit den Parametern instanziiert, die im Abschnitt Paginierung von Abfrageergebnissen erwähnt werden. Mehrere Seiten werden durch mehrmaliges Aufrufen der nextAsTwin-Methode aufgerufen.
Nächste Schritte
- Erfahren Sie mehr über das Routing von Nachrichten basierend auf Nachrichteneigenschaften oder dem Nachrichtentext mit der IoT Hub-Abfragesyntax für das Nachrichtenrouting.
- Erhalten Sie spezifische Beispiele für Abfragen für Geräte- und Modulzwillinge oder Abfragen für Aufträge.