共用方式為


數據處理者中的 jq 路徑表示式是什麼?

重要

已啟用 Azure Arc 的 Azure IoT 操作預覽版目前為預覽狀態。 請勿在生產環境使用此預覽版軟體。

當正式發行可供使用時,您將需要部署新的 Azure IoT 作業安裝,您將無法升級預覽安裝。

請參閱 Microsoft Azure 預覽版增補使用規定,以了解適用於 Azure 功能 (搶鮮版 (Beta)、預覽版,或尚未正式發行的版本) 的法律條款。

數據處理者中的許多管線階段都會使用 jq 路徑 表示式。 如須從訊息中擷取資訊,或將部分資訊放置於訊息中,請使用路徑。 jq 路徑可用於:

  • 在訊息中找出資訊片段。
  • 在訊息中找出要放置資訊片段的位置。

這兩種情況均使用相同的語法,並會根據訊息結構的根目錄指定位置。

數據處理者支援的 jq 路徑在語法上是正確的 jq,但已簡化語意,使其更容易使用,並協助減少數據處理者管線中的錯誤。 特別是,數據處理者不會使用 ? 語法來隱藏錯誤的數據結構。 使用路徑時,則會自動隱藏此類錯誤。

資料處理器管線中的資料存取範例包括彙總上次已知的值階段中的 inputPath。 如須存取資料處理者訊息中的部分資料,請使用資料存取模式。

資料更新使用與資料存取相同的語法,但特定更新狀況中包含部分特殊行為。 資料處理器管線中的資料更新範例包括彙總上次已知的值管線階段中的 outputPath。 每當您需要將作業的結果放入數據處理者訊息時,請使用數據更新模式。

注意

資料處理者訊息內不僅包含訊息本文, 也包含您傳送的所有屬性與中繼資料,以及其他相關系統資訊。 包含傳送至處理管線之資料的主要承載會放置於訊息根目錄的 payload 欄位中。 因此,本指南中許多範例皆包含以 .payload 開頭的路徑。

語法

每個 jq 路徑均由下列區段中的一個或多個序列組成:

  • 根路徑:.
  • 地圖或物件中的欄位,其使用下列其中一項值:
    • 針對英數字元物件鍵的 .<identifier>。 例如: .temperature
    • 針對任意物件鍵的 ."<identifier>"。 例如: ."asset-id"
    • ["<identifier>"] 或任意物件鍵。 例如: ["asset-id"]
  • 陣列索引:[<index>]。 例如,[2]

路徑必須一律以 . 開頭。 即使路徑以陣列或複雜的對應索引鍵開頭,最前方也必須加上 .。 路徑 .["complex-key"].[1].value 有效, 而路徑 ["complex-key"][1].value 無效。

範例訊息

下列資料存取和資料更新的範例將使用以下訊息,說明如何使用不同的路徑運算式:

{
  "systemProperties": {
    "partitionKey": "slicer-3345",
    "partitionId": 5,
    "timestamp": "2023-01-11T10:02:07Z"
  },
  "qos": 1,
  "topic": "assets/slicer-3345",
  "properties": {
    "responseTopic": "assets/slicer-3345/output",
    "contentType": "application/json"
  },
  "payload": {
    "Timestamp": 1681926048,
    "Payload": {
      "dtmi:com:prod1:slicer3345:humidity": {
        "sourceTimestamp": 1681926048,
        "value": 10
      },
      "dtmi:com:prod1:slicer3345:lineStatus": {
        "sourceTimestamp": 1681926048,
        "value": [1, 5, 2]
      },
      "dtmi:com:prod1:slicer3345:speed": {
        "sourceTimestamp": 1681926048,
        "value": 85
      },
      "dtmi:com:prod1:slicer3345:temperature": {
        "sourceTimestamp": 1681926048,
        "value": 46
      }
    },
    "DataSetWriterName": "slicer-3345",
    "SequenceNumber": 461092
  }
}

用於資料存取的根路徑

最基本的路徑即為根路徑,此路徑會指向訊息的根目錄,並傳回完整訊息。 請指定下列 jq 路徑:

.

結果如下:

{
  "systemProperties": {
    "partitionKey": "slicer-3345",
    "partitionId": 5,
    "timestamp": "2023-01-11T10:02:07Z"
  },
  "qos": 1,
  "topic": "assets/slicer-3345",
  "properties": {
    "responseTopic": "assets/slicer-3345/output",
    "contentType": "application/json"
  },
  "payload": {
    "Timestamp": 1681926048,
    "Payload": {
      "dtmi:com:prod1:slicer3345:humidity": {
        "sourceTimestamp": 1681926048,
        "value": 10
      },
      "dtmi:com:prod1:slicer3345:lineStatus": {
        "sourceTimestamp": 1681926048,
        "value": [1, 5, 2]
      },
      "dtmi:com:prod1:slicer3345:speed": {
        "sourceTimestamp": 1681926048,
        "value": 85
      },
      "dtmi:com:prod1:slicer3345:temperature": {
        "sourceTimestamp": 1681926048,
        "value": 46
      }
    },
    "DataSetWriterName": "slicer-3345",
    "SequenceNumber": 461092
  }
}

用於資料存取的簡單識別碼

以下為僅使用單一識別碼的最簡單路徑,在此案例中使用的為 payload 欄位。 請指定下列 jq 路徑:

.payload

提示

."payload".["payload"] 也可用於指定此路徑。 然而,若識別碼僅包含 a-zA-Z0-9_,則不須使用更複雜的語法。

結果如下:

{
  "Timestamp": 1681926048,
  "Payload": {
    "dtmi:com:prod1:slicer3345:humidity": {
      "SourceTimestamp": 1681926048,
      "Value": 10
    },
    "dtmi:com:prod1:slicer3345:lineStatus": {
      "SourceTimestamp": 1681926048,
      "Value": [1, 5, 2]
    },
    "dtmi:com:prod1:slicer3345:speed": {
      "SourceTimestamp": 1681926048,
      "Value": 85
    },
    "dtmi:com:prod1:slicer3345:temperature": {
      "SourceTimestamp": 1681926048,
      "Value": 46
    }
  },
  "DataSetWriterName": "slicer-3345",
  "SequenceNumber": 461092
}

用於資料存取的巢狀欄位

您可以結合路徑線段以擷取訊息中的深度巢狀資料,例如單一分葉值。 請指定下列兩個 jq 路徑之一:

.payload.Payload.["dtmi:com:prod1:slicer3345:temperature"].Value
.payload.Payload."dtmi:com:prod1:slicer3345:temperature".Value

結果如下:

46

用於資料存取的陣列元素

陣列元素的運作方式與對應索引鍵相同,不同之處僅在於 [] 中使用數字而非字串。 請指定下列兩個 jq 路徑之一:

.payload.Payload.["dtmi:com:prod1:slicer3345:lineStatus"].Value[1]
.payload.Payload."dtmi:com:prod1:slicer3345:lineStatus".Value[1]

結果如下:

5

資料存取中不存在且無效的路徑

若 jq 路徑指定的位置不存在,或與訊息結構不相容,則不會傳回任何值。

重要

部分處理階段必須具有某些值,若找不到任何值,則處理階段可能會失敗。 其他處理階段則設計為若無法在路徑中找到任何值,則會略過要求的作業或執行其他動作,繼續如常處理。

請指定下列 jq 路徑:

.payload[1].temperature

結果如下:

沒有任何值

用於資料更新的根路徑

最基本的路徑即為根路徑,此路徑會指向訊息的根目錄,並取代完整訊息。 請指定下列要插入的新值與 jq 路徑:

{ "update": "data" }
.

結果如下:

{ "update": "data" }

更新內容不會與先前的資料深度合併,而是取代進行更新之層級的資料。 為避免覆寫資料,請將更新範圍限制於要變更之最細部的路徑,或更新主要資料端的個別欄位。

用於資料更新的簡單識別碼

以下為僅使用單一識別碼的最簡單路徑,在此案例中使用的為 payload 欄位。 請指定下列要插入的新值與 jq 路徑:

{ "update": "data" }
.payload

提示

."payload".["payload"] 也可用於指定此路徑。 然而,若識別碼僅包含 a-zA-Z0-9_,則不須使用更複雜的語法。

結果如下:

{
  "systemProperties": {
    "partitionKey": "slicer-3345",
    "partitionId": 5,
    "timestamp": "2023-01-11T10:02:07Z"
  },
  "qos": 1,
  "topic": "assets/slicer-3345",
  "properties": {
    "responseTopic": "assets/slicer-3345/output",
    "contentType": "application/json"
  },
  "payload": { "update": "data" }
}

用於資料更新的巢狀欄位

您可以結合路徑線段以擷取訊息中的深度巢狀資料,例如單一分葉值。 請指定下列要插入的新值,以及下列兩個 jq 路徑之一:

{ "update": "data" }
.payload.Payload.["dtmi:com:prod1:slicer3345:temperature"].Value
.payload.Payload."dtmi:com:prod1:slicer3345:temperature".Value

結果如下:

{
  "systemProperties": {
    "partitionKey": "slicer-3345",
    "partitionId": 5,
    "timestamp": "2023-01-11T10:02:07Z"
  },
  "qos": 1,
  "topic": "assets/slicer-3345",
  "properties": {
    "responseTopic": "assets/slicer-3345/output",
    "contentType": "application/json"
  },
  "payload": {
    "Timestamp": 1681926048,
    "Payload": {
      "dtmi:com:prod1:slicer3345:humidity": {
        "sourceTimestamp": 1681926048,
        "value": 10
      },
      "dtmi:com:prod1:slicer3345:lineStatus": {
        "sourceTimestamp": 1681926048,
        "value": [1, 5, 2]
      },
      "dtmi:com:prod1:slicer3345:speed": {
        "sourceTimestamp": 1681926048,
        "value": 85
      },
      "dtmi:com:prod1:slicer3345:temperature": {
        "sourceTimestamp": 1681926048,
        "value": { "update": "data" }
      }
    },
    "DataSetWriterName": "slicer-3345",
    "SequenceNumber": 461092
  }
}

用於資料更新的陣列元素

陣列元素的運作方式與對應索引鍵相同,不同之處僅在於 [] 中使用數字而非字串。 請指定下列要插入的新值,以及下列兩個 jq 路徑之一:

{ "update": "data" }
.payload.Payload.["dtmi:com:prod1:slicer3345:lineStatus"].Value[1]
.payload.Payload."dtmi:com:prod1:slicer3345:lineStatus".Value[1]

結果如下:

{
  "systemProperties": {
    "partitionKey": "slicer-3345",
    "partitionId": 5,
    "timestamp": "2023-01-11T10:02:07Z"
  },
  "qos": 1,
  "topic": "assets/slicer-3345",
  "properties": {
    "responseTopic": "assets/slicer-3345/output",
    "contentType": "application/json"
  },
  "payload": {
    "Timestamp": 1681926048,
    "Payload": {
      "dtmi:com:prod1:slicer3345:humidity": {
        "sourceTimestamp": 1681926048,
        "value": 10
      },
      "dtmi:com:prod1:slicer3345:lineStatus": {
        "sourceTimestamp": 1681926048,
        "value": [1, { "update": "data" }, 2]
      },
      "dtmi:com:prod1:slicer3345:speed": {
        "sourceTimestamp": 1681926048,
        "value": 85
      },
      "dtmi:com:prod1:slicer3345:temperature": {
        "sourceTimestamp": 1681926048,
        "value": 46
      }
    },
    "DataSetWriterName": "slicer-3345",
    "SequenceNumber": 461092
  }
}

資料更新中不存在且類型不相符的路徑

若 jq 路徑指定的位置不存在,或與訊息結構不相容,則適用以下語意:

  • 如果不存在任何路徑線段,將會建立以下項目:
    • 針對物件索引鍵,索引鍵將新增至物件。
    • 針對陣列索引,陣列會以 null 值進行延長,使其足以包含所需的索引,接著更新索引。
    • 針對負數陣列索引,會執行相同的延長程序,但隨後將取代第一個元素。
  • 若路徑線段的類型與所需的類型不相符,則運算式會變更其類型,並捨棄該路徑位置的所有現有資料。

下列範例會使用與先前範例相同的輸入訊息,並插入下列新值:

{ "update": "data" }

請指定下列 jq 路徑:

.payload[1].temperature

結果如下:

{
  "systemProperties": {
    "partitionKey": "slicer-3345",
    "partitionId": 5,
    "timestamp": "2023-01-11T10:02:07Z"
  },
  "qos": 1,
  "topic": "assets/slicer-3345",
  "properties": {
    "responseTopic": "assets/slicer-3345/output",
    "contentType": "application/json"
  },
  "payload": [null, { "update": "data" }]
}

請指定下列 jq 路徑:

.payload.nested.additional.data

結果如下:

{
  "systemProperties": {
    "partitionKey": "slicer-3345",
    "partitionId": 5,
    "timestamp": "2023-01-11T10:02:07Z"
  },
  "qos": 1,
  "topic": "assets/slicer-3345",
  "properties": {
    "responseTopic": "assets/slicer-3345/output",
    "contentType": "application/json"
  },
  "payload": {
    "Timestamp": 1681926048,
    "Payload": {
      "dtmi:com:prod1:slicer3345:humidity": {
        "sourceTimestamp": 1681926048,
        "value": 10
      },
      "dtmi:com:prod1:slicer3345:lineStatus": {
        "sourceTimestamp": 1681926048,
        "value": [1, 5, 2]
      },
      "dtmi:com:prod1:slicer3345:speed": {
        "sourceTimestamp": 1681926048,
        "value": 85
      },
      "dtmi:com:prod1:slicer3345:temperature": {
        "sourceTimestamp": 1681926048,
        "value": 46
      }
    },
    "DataSetWriterName": "slicer-3345",
    "SequenceNumber": 461092,
    "nested": {
      "additional": {
        "data": { "update": "data" }
      }
    }
  }
}

請指定下列 jq 路徑:

.systemProperties.partitionKey[-4]

結果如下:

{
  "systemProperties": {
    "partitionKey": [{"update": "data"}, null, null, null],
    "partitionId": 5,
    "timestamp": "2023-01-11T10:02:07Z"
  },
  "qos": 1,
  "topic": "assets/slicer-3345",
  "properties": {
    "responseTopic": "assets/slicer-3345/output",
    "contentType": "application/json"
  },
  "payload": {
    "Timestamp": 1681926048,
    "Payload": {
      "dtmi:com:prod1:slicer3345:humidity": {
        "sourceTimestamp": 1681926048,
        "value": 10
      },
      "dtmi:com:prod1:slicer3345:lineStatus": {
        "sourceTimestamp": 1681926048,
        "value": [1, 5, 2]
      },
      "dtmi:com:prod1:slicer3345:speed": {
        "sourceTimestamp": 1681926048,
        "value": 85
      },
      "dtmi:com:prod1:slicer3345:temperature": {
        "sourceTimestamp": 1681926048,
        "value": 46
      }
    },
    "DataSetWriterName": "slicer-3345",
    "SequenceNumber": 461092,
  }