裝置與模組對應項、作業和訊息路由的 IoT 中樞查詢語言
IoT 中樞提供功能強大、類似 SQL 的語言,以擷取有關裝置對應項、模組對應項、作業和訊息路由的資訊。 本文提供︰
- IoT 中樞查詢語言主要功能的簡介,以及
- 語言的詳細說明。 如需訊息路由查詢語言的詳細資訊,請參閱訊息路由中的查詢。
如需特定範例,請參閱裝置和模組對應項的查詢或作業的查詢。
注意
本文中提及的某些功能 (例如雲端對裝置傳訊、裝置對應項和裝置管理) 僅適用於 IoT 中樞的標準層。 如需有關基本和標準/免費 Azure IoT 中樞階層的詳細資訊,請參閱為您的解決方案選擇適合的 Azure IoT 中樞階層。
執行 IoT 中樞查詢
您可以直接在 Azure 入口網站中對 IoT 中樞執行查詢。
- 登入 Azure 入口網站,然後瀏覽至 IoT 中樞。
- 從導覽功能表的 [裝置管理] 區段中選取 [查詢]。
- 在文字方塊中輸入查詢,並選取 [執行查詢]
您也可以使用 Azure IoT 服務 SDK 和服務 API,在應用程式中執行查詢。
如需實作 IoT 中樞查詢的範例程式碼,請參閱使用服務 SDK 的查詢範例一節。
如需 SDK 參考頁面和範例的連結,請參閱 Azure IoT SDK。
IoT 中樞查詢的基本概念
每個「IoT 中樞」查詢都包含 SELECT 和 FROM 子句,以及選擇性的 WHERE 和 GROUP BY 子句。
查詢都會在 JSON 文件的集合上執行,例如裝置對應項。 FROM 子句會指出要在其上反覆運算的文件集合 (devices、devices.modules 或 devices.jobs)。
然後,會套用 WHERE 子句中的篩選。 使用彙總時,此步驟的結果會依照 GROUP BY 子句中所指定的方式進行分組。 針對每個群組,會依照 SELECT 子句中所指定的方式產生一個資料列。
SELECT <select_list>
FROM <from_specification>
[WHERE <filter_condition>]
[GROUP BY <group_specification>]
SELECT 子句
每個 IoT 中樞查詢都需要 SELECT <select_list> 子句。 該子句會指定要從查詢中擷取哪些值。 它會指定用來產生新 JSON 物件的 JSON 值。 針對已篩選 (及視需要已分組) 之 FROM 集合子集的每個項目,投影階段會產生一個新的 JSON 物件。 此物件會以 SELECT 子句中所指定的值來建構。
例如:
傳回所有值
SELECT *
傳回特定屬性
SELECT DeviceID, LastActivityTime
彙總查詢的結果以傳回計數
SELECT COUNT() as TotalNumber
目前,只有在裝置對應項的彙總查詢中,才支援與 SELECT 不同的選取範圍子句。
下列語法是 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 指的是 FROM 集合中 JSON 文件的任何屬性。
FROM 子句
每個 IoT 中樞查詢都需要 FROM <from_specification> 子句。 必須是下列三個值中的其中一個:
- devices,用來查詢裝置對應項
- devices.modules,用來查詢模組對應項
- devices.jobs,用來查詢每個裝置的作業詳細資料
例如:
擷取所有裝置對應項
SELECT * FROM devices
WHERE 子句
WHERE <filter_condition> 子句是選擇性的。 它會指定一或多個條件,而且 FROM 集合中的 JSON 文件必須滿足這些條件,才能納入為結果的一部分。 任何 JSON 文件都必須將指定的條件評估為 "true",才能併入結果。
例如:
擷取以特定裝置為目標的所有作業
SELECT * FROM devices.jobs WHERE devices.jobs.deviceId = 'myDeviceId'
運算式和條件一節中會說明允許的條件。
GROUP BY 子句
可以選用 GROUP BY <group_specification> 子句。 此子句會在 WHERE 子句中指定的篩選之後、SELECT 中指定的投影之前執行。 它會根據屬性值來分組文件。 這些群組可用來產生 SELECT 子句中所指定的彙總值。
例如:
傳回報告每個遙測設定狀態的裝置計數
SELECT properties.reported.telemetryConfig.status AS status, COUNT() AS numberOfDevices FROM devices GROUP BY properties.reported.telemetryConfig.status
目前,GROUP BY 子句只支援在查詢裝置對應項時使用。
警告
group
一詞目前被視為查詢中的特殊關鍵字。 萬一您使用 group
作為屬性名稱,請考慮使用雙括號括住,以避免發生錯誤,例如 SELECT * FROM devices WHERE tags.[[group]].name = 'some_value'
。
GROUP BY 的正式語法如下︰
GROUP BY <group_by_element>
<group_by_element> :==
attribute_name
| < group_by_element > '.' attribute_name
attribute_name 指的是 FROM 集合中 JSON 文件的任何屬性。
查詢結果分頁
查詢物件會以小於或等於 100 筆記錄的最大頁面大小 具現化。 若要取得多個頁面,請在 Node.js SDK 上呼叫 nextAsTwin,或在 .Net SDK 方法上呼叫 GetNextAsTwinAsync 多次。 query 物件可根據查詢所需的還原序列化選項,公開多個 Next 值。 例如,查詢物件可以在使用投影時傳回裝置對應項或作業物件,或純 JSON。
運算式和條件
概括而言,運算式:
- 會評估為 JSON 類型 (例如布林值、數字、字串、陣列或物件) 的執行個體。
- 定義方式是使用內建運算子和函式處理來自裝置 JSON 文件和常數的資料。
「條件」是評估為布林值的運算式。 任何與布林值 true 不同的常數都會被視為 false。 此規則包括 nullundefined、任何物件或陣列執行個體、任何字串,以及布林值 false。
運算式的語法如下︰
<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>]+ ']'
若要了解運算式語法中每個符號所代表的意義,請參閱下表:
符號 | 定義 |
---|---|
attribute_name | FROM 集合中 JSON 文件的任何屬性。 |
binary_operator | 運算子一節中所列的任何二元運算子。 |
function_name | 函式一節中所列的任何函式。 |
decimal_literal | 以小數點標記法表示的浮點數。 |
hexadecimal_literal | 以字串 '0x' 後面接著十六進位數字的字串所表示的數字。 |
string_literal | 由零個或多個 Unicode 字元序列或逸出序列所表示的 Unicode 字串。 字串常值會以單引號或雙引號括起來。 允許的逸出︰\' 、\" 、\\ 、\uXXXX (適用於由四個十六進位數字所定義的 Unicode 字元)。 |
操作員
支援下列運算子:
系列 | 操作員 |
---|---|
算術 | |
邏輯 | AND、OR、NOT |
比較 |
函式
查詢對應項和作業時唯一支援的函式為:
函式 | 描述 |
---|---|
IS_DEFINED(property) | 傳回布林值,表示屬性是否已經指派值 (包含 null )。 |
在路由條件中,支援下列比對函式:
函式 | 描述 |
---|---|
ABS(x) | 傳回指定之數值運算式的絕對 (正) 值。 |
EXP(x) | 傳回指定之數值運算式 (e^x) 的指數值。 |
POWER(x,y) | 將指定之運算式的值傳回給指定的乘冪 (x^y)。 |
SQUARE(x) | 傳回指定之數值的平方。 |
CEILING(x) | 傳回大於或等於指定之數值運算式的最小整數值。 |
FLOOR(x) | 傳回小於或等於指定數值運算式的最大整數。 |
SIGN(x) | 傳回指定之數值運算式的正數 (+1)、零 (0) 或負數 (-1) 符號。 |
SQRT(x) | 傳回指定之數值的平方根。 |
在路由條件中,支援下列類型檢查和轉換函式:
函式 | 描述 |
---|---|
AS_NUMBER | 將輸入字串轉換為數字。 如果輸入是一個數字則為 noop ;如果字串不是數字則為 Undefined 。 |
IS_ARRAY | 傳回布林值,表示指定之運算式的類型為陣列。 |
IS_BOOL | 傳回布林值,表示指定之運算式的型別為布林值。 |
IS_DEFINED | 傳回布林值,表示屬性是否已經指派值。 只有在值是基本類型時,才支援此函式。 基本類型包括字串、布林值、數值或 null 。 不支援 DateTime、物件類型和陣列。 |
IS_NULL | 傳回布林值,表示指定之運算式的型別為 null。 |
IS_NUMBER | 傳回布林值,表示指定之運算式的型別為數值。 |
IS_OBJECT | 傳回布林值,表示指定之運算式的型別為 JSON 物件。 |
IS_PRIMITIVE | 傳回布林值,可指出所指定之運算式的類型是否為基本類型 (字串、布林值、數值或 null )。 |
IS_STRING | 傳回布林值,表示指定之運算式的型別為字串。 |
在路由條件中,支援下列字串函式:
函式 | 描述 |
---|---|
CONCAT(x, y, …) | 傳回字串,該字串是串連兩個或多個字串值的結果。 |
LENGTH(x) | 傳回指定字串運算式的字元數目。 |
LOWER(x) | 傳回將大寫字元資料轉換成小寫之後的字串運算式。 |
UPPER(x) | 傳回將小寫字元資料轉換成大寫之後的字串運算式。 |
SUBSTRING(string, start [, length]) | 傳回字串運算式的部分,從指定字元以零為起始的位置開始,直到指定的長度,或直到字串的結尾。 |
INDEX_OF(string, fragment) | 傳回第一個指定的字串運算式中,第二個字串運算式第一次出現的開始位置;如果找不到字串,則為 -1。 |
STARTSWITH(x, y) | 傳回布林值,表示第一個字串運算式是否以第二個字串運算式開頭。 |
ENDSWITH(x, y) | 傳回布林值,表示第一個字串運算式是否以第二個字串運算式結尾。 |
CONTAINS(x,y) | 傳回布林值,表示第一個字串運算式是否包含第二個字串運算式。 |
使用服務 SDK 查詢範例
C# 範例
查詢功能由 C# 服務 SDK 在 RegistryManager 類別中公開。
以下是簡單查詢的範例︰
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
}
}
查詢物件會使用查詢結果分頁一節中所述的參數具現化。 藉由呼叫 GetNextAsTwinAsync 方法多次來擷取多個頁面。
Node.js 範例
查詢功能由適用於 Node.js 的 Azure IoT 服務 SDK 在 Registry 物件中公開。
以下是簡單查詢的範例︰
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);
查詢物件會使用查詢結果分頁一節中所述的參數具現化。 藉由呼叫 nextAsTwin 方法多次來擷取多個頁面。
下一步
- 請參閱 IoT 中樞訊息路由查詢語法,深入了解根據訊息屬性或訊息本文的路由訊息。
- 取得裝置和模組對應項的查詢或作業的查詢的特定範例。