IoT 中樞訊息路由查詢語法 \(部分機器翻譯\)
訊息路由可讓使用者將不同的資料類型 (包括裝置遙測訊息、裝置生命週期事件和裝置對應項變更事件) 路由傳送至各個端點。 您也可以在路由此資料之前先套用豐富查詢,以僅接收對您而言最重要的資料。 此文會說明 IoT 中樞訊息路由查詢語言,並提供一些常見的查詢模式。
注意
本文中提及的某些功能 (例如雲端對裝置傳訊、裝置對應項和裝置管理) 僅適用於 IoT 中樞的標準層。 如需有關基本和標準/免費 IoT 中樞層的詳細資訊,請參閱為您的解決方案選擇適合的 IoT 中樞層。
訊息路由可讓您對訊息屬性和訊息本文,以及裝置對應項標記和裝置對應項屬性進行查詢。 如果訊息本文並非 JSON,訊息路由仍可以路由該訊息,但將無法將查詢套用至訊息本文。 查詢會描述為布林運算式,如果為 true,則查詢會成功,並路由傳送所有傳入資料;否則,查詢會失敗,且不會路由傳送傳入資料。 如果運算式評估為 Null 或未定義的值,則會將其視為布林值 false 值,並在 IoT 中樞路由資源記錄中產生錯誤。 查詢語法必須正確,才能儲存並評估路由。
根據訊息屬性進行查詢
IoT 中樞會針對所有裝置到雲端訊息定義常見格式,以在通訊協定之間提供互通性。 IoT 中樞會針對訊息假設下列 JSON 表示法。 系統會針對訊息的所有使用者和身分識別內容新增系統屬性。 使用者可以選擇性地將應用程式屬性新增至訊息。 建議使用唯一屬性名稱,因為 IoT 中樞的裝置到雲端訊息並不區分大小寫。 例如,如果您有多個具相同名稱的屬性,IoT 中樞將只會傳送其中一個屬性。
{
"message": {
"systemProperties": {
"contentType": "application/json",
"contentEncoding": "UTF-8",
"iothub-message-source": "deviceMessages",
"iothub-enqueuedtime": "2017-05-08T18:55:31.8514657Z"
},
"appProperties": {
"processingPath": "{cold | warm | hot}",
"verbose": "{true, false}",
"severity": 1-5,
"testDevice": "{true | false}"
},
"body": "{\"Weather\":{\"Temperature\":50}}"
}
}
系統屬性
系統屬性有助於識別訊息的內容和來源,下表說明其中一些內容:
屬性 | 類型 | 描述 |
---|---|---|
contentType | string | 使用者會指定訊息的內容類型。 若要允許對訊息本文進行查詢,此值應該設定為 application/JSON 。 |
contentEncoding | string | 使用者會指定訊息的編碼類型。 如果 contentType 屬性設定為 application/JSON ,則允許的值為 UTF-8 、UTF-16 和 UTF-32 。 |
iothub-connection-device-id | string | 此值是由 IoT 中樞設定,並能識別裝置的識別碼。 若要查詢,請使用 $connectionDeviceId 。 |
iothub-connection-module-id | string | 此值由 IoT 中樞設定,且能識別邊緣模組的識別碼。 若要查詢,請使用 $connectionModuleId 。 |
iothub-enqueuedtime | string | 此值是由 IoT 中樞設定,並代表將訊息加入佇列的實際時間 (以 UTC 表示)。 若要查詢,請使用 $enqueuedTime 。 |
dt-dataschema | string | 此值由 IoT 中樞在裝置到雲端訊息上所設定。 其包含裝置連線中設定的裝置型號識別碼。 若要查詢,請使用 $dt-dataschema 。 |
dt-subject | string | 傳送裝置到雲端訊息的元件名稱。 若要查詢,請使用 $dt-subject 。 |
如需其他可用系統屬性的詳細資訊,請參閱建立及讀取 IoT 中樞訊息。
應用程式屬性
應用程式屬性是可新增至訊息的使用者定義字串。 這些欄位是選擇性的。
訊息屬性查詢運算式
訊息系統屬性的查詢前面必須加上 $
符號。 針對應用程式屬性的查詢是透過屬性名稱來存取,因此前面不應該加上 $
符號。 如果應用程式屬性名稱開頭為 $
,則 IoT 中樞將會在系統屬性中加以搜尋,在找不到的情況下,則會在應用程式屬性中搜尋。 下列範例示範如何查詢系統屬性和應用程式屬性。
若要查詢系統屬性 contentEncoding:
$contentEncoding = 'UTF-8'
若要查詢應用程式屬性 processingPath:
processingPath = 'hot'
若要合併這些查詢,您可以使用布林運算式和函式:
$contentEncoding = 'UTF-8' AND processingPath = 'hot'
裝置與模組對應項、作業和訊息路由的 IoT 中樞查詢語言的運算式和條件區段中,提供支援的運算子和函式的完整清單。
根據訊息本文進行查詢
若要啟用針對訊息本文的查詢,訊息應為 JSON 格式及以 UTF-8、UTF-16 或 UTF-32 編碼。 contentType
系統屬性必須是 application/JSON
。 contentEncoding
系統屬性必須是該系統屬性支援的其中一個 UTF 編碼值。 如果未指定這些系統屬性,IoT 中樞不會針對訊息本文評估查詢運算式。
下列 JavaScript 範例說明如何以經過正確格式化和編碼的 JSON 主體建立訊息:
var messageBody = JSON.stringify(Object.assign({}, {
"Weather": {
"Temperature": 50,
"Time": "2017-03-09T00:00:00.000Z",
"PrevTemperatures": [
20,
30,
40
],
"IsEnabled": true,
"Location": {
"Street": "One Microsoft Way",
"City": "Redmond",
"State": "WA"
},
"HistoricalData": [
{
"Month": "Feb",
"Temperature": 40
},
{
"Month": "Jan",
"Temperature": 30
}
]
}
}));
// Encode message body using UTF-8
var messageBytes = Buffer.from(messageBody, "utf8");
var message = new Message(messageBytes);
// Set message body type and content encoding
message.contentEncoding = "utf-8";
message.contentType = "application/json";
// Add other custom application properties
message.properties.add("Status", "Active");
deviceClient.sendEvent(message, (err, res) => {
if (err) console.log('error: ' + err.toString());
if (res) console.log('status: ' + res.constructor.name);
});
如需以 C# 編碼範例的訊息,請參閱適用於 .NET 的 Microsoft Azure IoT SDK 中提供的 HubRoutingSample。 此範例與訊息路由教學課程中使用的範例相同。 Program.cs 檔案也有一個名為 ReadOneRowFromFile
的方法,可在其中一個編碼的檔案中讀取檔案、加以解碼,並以 ASCII 形式將其寫回,讓您能夠加以讀取。
訊息本文查詢運算式
針對訊息本文的查詢,需要在前面加上 $body
。 您可以在查詢運算式中使用本文參考、本文陣列參考或多個本文參考。 您的查詢運算式也可以將本文參考與訊息系統屬性參考或訊息應用程式屬性參考進行結合。 例如,以下是所有有效查詢運算式的範例:
$body.Weather.HistoricalData[0].Month = 'Feb'
$body.Weather.Temperature = 50 AND $body.Weather.IsEnabled
length($body.Weather.Location.State) = 2
$body.Weather.Temperature = 50 AND processingPath = 'hot'
您只能針對本文參考中的屬性執行查詢和函式。 您無法針對整個本文參考執行查詢或函式。 例如,「不」支援下列查詢且將傳回 undefined
:
$body[0] = 'Feb'
若要根據變更的內容篩選對應項通知承載,請針對訊息本文執行您的查詢。 例如,在 sendFrequency
上有所需的屬性變更且值大於 10 時進行篩選:
$body.properties.desired.telemetryConfig.sendFrequency > 10
若要篩選包含屬性變更的訊息,不論屬性的值為何,您都可以使用 is_defined()
函式 (當值為基本類型時):
is_defined($body.properties.desired.telemetryConfig.sendFrequency)
根據裝置或模組對應項進行查詢
訊息路由可讓您針對裝置對應項或模組對應項標記和屬性 (其為 JSON 物件) 進行查詢。 下列範例說明具有標籤和屬性的裝置對應項:
{
"tags": {
"deploymentLocation": {
"building": "43",
"floor": "1"
}
},
"properties": {
"desired": {
"telemetryConfig": {
"sendFrequency": "5m"
},
"$metadata" : {...},
"$version": 1
},
"reported": {
"telemetryConfig": {
"sendFrequency": "5m",
"status": "success"
},
"batteryLevel": 55,
"$metadata" : {...},
"$version": 4
}
}
}
注意
模組不會從其對應的裝置繼承對應項標記。 針對源自裝置模組 (例如來自 IoT Edge 模組) 的訊息所進行的對應項查詢會針對模組對應項 (而不是針對相對應的裝置對應項) 進行查詢。
對應項查詢運算式
針對裝置對應項或模組對應項的查詢前面必須加上 $twin
。 您的查詢運算式也可以將對應項標記或屬性參考,與本文參考、訊息系統屬性參考,或訊息應用程式屬性參考合併。 我們建議在標記和屬性中使用唯一名稱,因為查詢不區分大小寫。 此建議適用於裝置對應項和模組對應項。 也建議您避免使用 twin
、$twin
、body
或 $body
做為屬性名稱。 例如,以下是所有有效查詢運算式的範例:
$twin.properties.desired.telemetryConfig.sendFrequency = '5m'
$body.Weather.Temperature = 50 AND $twin.properties.desired.telemetryConfig.sendFrequency = '5m'
$twin.tags.deploymentLocation.floor = 1
限制
路由查詢不支援在屬性名稱、訊息內文路徑或裝置/模組對應項路徑中使用空白字元或下列任何字元:()<>@,;:\"/?={}
。