探討訊息路由查詢

已完成

訊息路由可讓使用者將不同的資料類型,包含裝置遙測訊息、裝置生命週期事件,以及裝置對應項變更事件路由傳送至各個端點。 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/JSONcontentEncoding 系統屬性必須是該系統屬性所支援其中一個支援的 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$twinbody$body 作為屬性名稱。 例如,下列是所有有效的查詢運算式:

$twin.properties.desired.telemetryConfig.sendFrequency = '5m'

$body.Weather.Temperature = 50 AND $twin.properties.desired.telemetryConfig.sendFrequency = '5m'

$twin.tags.deploymentLocation.floor = 1 

限制

路由查詢不支援在屬性名稱、訊息本文路徑或裝置/模組對應項路徑中使用空格或下列任何字元:()<>@,;:\"/?={}