探討訊息路由查詢
訊息路由可讓使用者將不同的資料類型,包含裝置遙測訊息、裝置生命週期事件,以及裝置對應項變更事件路由傳送至各個端點。 Azure IoT 中樞訊息路由會提供查詢功能,在將資料路由傳送到端點前先篩選資料。
單一訊息可能符合多個路由查詢的條件,在這種情況下,Azure IoT 中樞會將訊息傳遞至與每個相符查詢相關聯的端點。 Azure IoT 中樞也會自動刪除重複的訊息傳遞,因此,如果訊息符合多個具有相同目的地的查詢,該訊息就只會寫入到該目的地一次。
您設定的每個路由查詢都具有下列屬性:
屬性
說明
Name
可識別查詢的唯一名稱。
來源
要據以處理的資料串流來源。 例如裝置遙測。
Condition
適用於路由查詢的查詢運算式,會針對訊息應用程式屬性、系統屬性、訊息本文、裝置對應項標籤和裝置對應項屬性來執行,以判斷它是否符合端點。
端點
Azure IoT 中樞傳送符合查詢之訊息的目的地端點名稱。 我們建議選擇與您 Azure IoT 中樞位於相同區域的端點。
訊息路由查詢語法
訊息路由可讓您對訊息屬性和訊息本文,以及裝置對應項標記和裝置對應項屬性進行查詢。 如果訊息本文不是 JSON 格式,訊息路由仍可以路由該訊息,但將無法把查詢套用至訊息本文。 查詢會描述為布林運算式,如果為 true,則查詢會成功並路由傳送所有傳入資料;否則,查詢會失敗,且傳入的資料不會路由傳送。 如果運算式評估為 null 或未定義的值,則會將其視為布林值 false 值,並在 Azure IoT 中樞路由資源記錄中產生錯誤。 查詢語法必須正確,才能儲存並評估路由。
以訊息屬性為基礎的訊息路由查詢
Azure IoT 中樞會針對所有裝置到雲端訊息定義常見格式,以在通訊協定之間提供互通性。 Azure IoT 中樞會針對訊息假設下列 JSON 表示法。
- 系統會為所有使用者新增系統屬性 (systemProperties),並識別訊息的內容。
- 使用者可以選擇性地將應用程式屬性 (appProperties) 新增至訊息。 應用程式屬性是使用者定義的字串。 我們建議使用唯一屬性名稱,因為 Azure IoT 中樞的裝置到雲端的傳訊不會區分大小寫。 例如,如果您有多個具相同名稱的屬性,Azure 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}}"
}
}
訊息屬性查詢運算式
針對訊息系統屬性的查詢前面必須加上 $
符號。 對應用程式屬性的查詢是透過屬性名稱來存取的,因此不應該其前面加上 $
符號。 如果應用程式屬性名稱的開頭是 $
,則 Azure IoT 中樞會在系統屬性中搜尋它,並在找不到它的情況下於應用程式屬性中尋找它。 下列範例示範如何查詢系統屬性和應用程式屬性。
查詢系統屬性 contentEncoding:
$contentEncoding = 'UTF-8'
查詢應用程式屬性 processingPath:
processingPath = 'hot'
若要合併這些查詢,您可以使用布林運算式和函式:
$contentEncoding = 'UTF-8' AND processingPath = 'hot'
如需支援運算子和函式的完整清單,請參閱裝置與模組對應項、作業和訊息路由的 IoT 中樞查詢語言的運算式和條件一節。
以訊息本文為基礎的訊息路由查詢
若要啟用針對訊息本文的查詢,訊息必須是 UTF-8、UTF-16 或 UTF-32 編碼的 JSON 格式檔案。 contentType
必須設定為 application/JSON
。 contentEncoding
系統屬性必須是該系統屬性所支援其中一個支援的 UTF 編碼。 如果未指定這些屬性,Azure IoT 中樞將不會針對訊息本文評估查詢運算式。
下列範例說明如何以經過正確格式化和編碼的 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);
});
根據訊息本文查詢訊息路由查詢的查詢運算式
對訊息本文的查詢必須加上 $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
限制
路由查詢不支援在屬性名稱、訊息本文路徑或裝置/模組對應項路徑中使用空格或下列任何字元:()<>@,;:\"/?={}
。