Dela via


Vad är jq-sökvägsuttryck i förhandsversionen av Azure IoT Data Processor?

Viktigt!

Förhandsversion av Azure IoT Operations – aktiverad av Azure Arc finns för närvarande i FÖRHANDSVERSION. Du bör inte använda den här förhandsgranskningsprogramvaran i produktionsmiljöer.

Juridiska villkor för Azure-funktioner i betaversion, förhandsversion eller som av någon annan anledning inte har gjorts allmänt tillgängliga ännu finns i kompletterande användningsvillkor för Microsoft Azure-förhandsversioner.

Många pipelinesteg i Förhandsversionen av Azure IoT Data Processor använder jq-sökvägsuttryck . När du behöver hämta information från ett meddelande eller placera viss information i ett meddelande använder du en sökväg. Med jq-sökvägar kan du:

  • Leta upp en del information i ett meddelande.
  • Identifiera var du ska placera en information i ett meddelande.

Båda fallen använder samma syntax och anger platser i förhållande till roten i meddelandestrukturen.

Jq-sökvägarna som stöds av dataprocessorn är syntaktiskt korrekta för jq, men har förenklad semantik för att göra dem enklare att använda och för att minska felen i dataprocessorns pipleline. I synnerhet använder dataprocessorn inte syntaxen ? för att förhindra fel för feljusterade datastrukturer. Dessa fel undertrycks automatiskt för dig när du arbetar med sökvägar.

Exempel på dataåtkomst i en databehandlingspipeline är inputPath i aggregerade och senast kända värdesteg. Använd dataåtkomstmönstret när du behöver komma åt vissa data i ett databehandlingsmeddelande.

Datauppdatering använder samma syntax som dataåtkomst, men det finns vissa särskilda beteenden i specifika uppdateringsscenarier. Exempel på datauppdatering i en databehandlingspipeline är outputPath i stegen för sammanställd och senast känd värdepipeline . Använd datauppdateringsmönstret när du behöver placera resultatet av en åtgärd i dataprocessormeddelandet.

Kommentar

Ett databehandlingsmeddelande innehåller mer än bara brödtexten i meddelandet. Ett databehandlingsmeddelande innehåller alla egenskaper och metadata som du har skickat och annan relevant systeminformation. Den primära nyttolasten som innehåller data som skickas till bearbetningspipelinen placeras i ett payload fält i meddelandets rot. Därför innehåller många av exemplen i den här guiden sökvägar som börjar med .payload.

Syntax

Varje jq-sökväg består av en sekvens av ett eller flera av följande segment:

  • Rotsökvägen: ..
  • Ett fält i en karta eller ett objekt som använder något av:
    • .<identifier> för alfanumeriska objektnycklar. Exempel: .temperature
    • ."<identifier>" för godtyckliga objektnycklar. Exempel: ."asset-id"
    • ["<identifier>"] eller godtyckliga objektnycklar. Exempel: ["asset-id"]
  • Ett matrisindex: [<index>]. Till exempel[2].

Sökvägar måste alltid börja med .. Även om du har en matris eller en komplex kartnyckel i början av sökvägen måste det finnas en . som föregår den. Sökvägarna .["complex-key"] och .[1].value är giltiga. Sökvägarna ["complex-key"] och [1].value är ogiltiga.

Exempelmeddelande

Följande exempel på dataåtkomst och datauppdatering använder följande meddelande för att illustrera användningen av olika sökvägsuttryck:

{
  "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
  }
}

Rotsökväg för dataåtkomst

Den mest grundläggande sökvägen är rotsökvägen, som pekar på meddelandets rot och returnerar hela meddelandet. Med följande jq-sökväg:

.

Resultatet är:

{
  "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
  }
}

Enkel identifierare för dataåtkomst

Nästa enklaste sökväg omfattar en enda identifierare, i det här fallet fältet payload . Med följande jq-sökväg:

.payload

Dricks

."payload" och .["payload"] är också giltiga sätt att ange den här sökvägen. Identifierare som bara innehåller a-z, A-Z0-9 och _ som inte kräver den mer komplexa syntaxen.

Resultatet är:

{
  "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
}

Kapslade fält för dataåtkomst

Du kan kombinera sökvägssegment för att hämta data som är kapslade djupt i meddelandet, till exempel ett enskilt lövvärde. Med någon av följande två jq-sökvägar:

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

Resultatet är:

46

Matriselement för dataåtkomst

Matriselement fungerar på samma sätt som kartnycklar, förutom att du använder ett tal på plats med en sträng i[]. Med någon av följande två jq-sökvägar:

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

Resultatet är:

5

Obefintliga och ogiltiga sökvägar i dataåtkomst

Om en jq-sökväg identifierar en plats som inte finns eller inte är kompatibel med meddelandets struktur returneras inget värde.

Viktigt!

Vissa bearbetningssteg kräver att ett visst värde finns och kan misslyckas om inget värde hittas. Andra är utformade för att fortsätta bearbetningen normalt och antingen hoppa över den begärda åtgärden eller utföra en annan åtgärd om inget värde hittas på sökvägen.

Med följande jq-sökväg:

.payload[1].temperature

Resultatet är:

Inget värde

Rotsökväg för datauppdatering

Den mest grundläggande sökvägen är rotsökvägen, som pekar på meddelandets rot och ersätter hela meddelandet. Med följande nya värde att infoga och jq sökväg:

{ "update": "data" }
.

Resultatet är:

{ "update": "data" }

Uppdateringar är inte djupt sammanfogade med tidigare data, utan ersätter i stället data på den nivå där uppdateringen sker. Undvik att skriva över data genom att begränsa uppdateringen till den mest detaljerade sökvägen som du vill ändra eller uppdatera ett separat fält till sidan av dina primära data.

Enkel identifierare för datauppdatering

Nästa enklaste sökväg omfattar en enda identifierare, i det här fallet fältet payload . Med följande nya värde att infoga och jq sökväg:

{ "update": "data" }
.payload

Dricks

."payload" och .["payload"] är också giltiga sätt att ange den här sökvägen. Identifierare som bara innehåller a-z, A-Z0-9 och _ som inte kräver den mer komplexa syntaxen.

Resultatet är:

{
  "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" }
}

Kapslade fält för datauppdatering

Du kan kombinera sökvägssegment för att hämta data som är kapslade djupt i meddelandet, till exempel ett enskilt lövvärde. Med följande nya värde att infoga och någon av följande två jq-sökvägar:

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

Resultatet är:

{
  "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
  }
}

Matriselement för datauppdatering

Matriselement fungerar på samma sätt som kartnycklar, förutom att du använder ett tal på plats med en sträng i[]. Med följande nya värde att infoga och någon av följande två jq-sökvägar:

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

Resultatet är:

{
  "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
  }
}

Icke-existerande och typmatchade sökvägar i datauppdatering

Om en jq-sökväg identifierar en plats som inte finns eller inte är kompatibel med meddelandets struktur gäller följande semantik:

  • Om det inte finns några segment av sökvägen skapas de:
    • För objektnycklar läggs nyckeln till i objektet.
    • För matrisindex förlängs matrisen med null värden så att den blir tillräckligt lång för att ha det index som krävs, och sedan uppdateras indexet.
    • För negativa matrisindex sker samma förlängda procedur, men sedan ersätts det första elementet.
  • Om ett sökvägssegment har en annan typ än vad det behöver ändrar uttrycket typen och tar bort alla befintliga data på sökvägen.

I följande exempel används samma indatameddelande som i föregående exempel och infogar följande nya värde:

{ "update": "data" }

Med följande jq-sökväg:

.payload[1].temperature

Resultatet är:

{
  "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" }]
}

Med följande jq-sökväg:

.payload.nested.additional.data

Resultatet är:

{
  "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" }
      }
    }
  }
}

Med följande jq-sökväg:

.systemProperties.partitionKey[-4]

Resultatet är:

{
  "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,
  }