Convertire i dati usando le conversioni dei flussi di dati

Importante

Anteprima di Operazioni di Azure IoT – Abilitata da Azure Arc è attualmente in anteprima. Non è consigliabile usare questo software di anteprima negli ambienti di produzione.

Sarà necessario distribuire una nuova installazione di Operazioni di Azure IoT quando sarà messa a disposizione una versione disponibile a livello generale. Non sarà possibile aggiornare un'installazione di anteprima.

Vedere le condizioni per l'utilizzo supplementari per le anteprime di Microsoft Azure per termini legali aggiuntivi che si applicano a funzionalità di Azure in versione beta, in anteprima o in altro modo non ancora disponibili a livello generale.

È possibile usare le conversioni dei flussi di dati per trasformare i dati nelle operazioni IoT di Azure. L'elemento di conversione in un flusso di dati viene usato per calcolare i valori per i campi di output. È possibile usare campi di input, operazioni disponibili, tipi di dati e conversioni di tipi nelle conversioni dei flussi di dati.

L'elemento di conversione del flusso di dati viene usato per calcolare i valori per i campi di output:

inputs: [
  '*.Max' // - $1
  '*.Min' // - $2
]
output: 'ColorProperties.*'
expression: '($1 + $2) / 2'

Esistono diversi aspetti da comprendere sulle conversioni:

  • Riferimento ai campi di input: come fare riferimento ai valori dei campi di input nella formula di conversione.
  • Operazioni disponibili: operazioni che possono essere utilizzate nelle conversioni. Ad esempio, addizione, sottrazione, moltiplicazione e divisione.
  • Tipi di dati: tipi di dati che una formula può elaborare e modificare. Ad esempio, integer, a virgola mobile e stringa.
  • Conversioni dei tipi: modalità di conversione dei tipi di dati tra i valori dei campi di input, la valutazione della formula e i campi di output.

Campi di input

Nelle conversioni, le formule possono operare su valori statici come un numero, ad esempio 25 o parametri derivati dai campi di input. Un mapping definisce questi campi di input a cui la formula può accedere. Ogni campo viene fatto riferimento in base all'ordine nell'elenco di input:

inputs: [
  '*.Max'      // - $1
  '*.Min'      // - $2
  '*.Mid.Avg'  // - $3
  '*.Mid.Mean' // - $4
]
output: 'ColorProperties.*'
expression: '($1, $2, $3, $4)'

In questo esempio la conversione restituisce una matrice contenente i valori di [Max, Min, Mid.Avg, Mid.Mean]. I commenti nel file YAML (# - $1, # - $2) sono facoltativi, ma consentono di chiarire la connessione tra ogni proprietà del campo e il relativo ruolo nella formula di conversione.

Tipo di dati

Diversi formati di serializzazione supportano vari tipi di dati. Ad esempio, JSON offre alcuni tipi primitivi: string, number, Boolean e Null. Sono incluse anche matrici di questi tipi primitivi. Al contrario, altri formati di serializzazione come Avro hanno un sistema di tipi più complesso, inclusi numeri interi con più lunghezze di campo di bit e timestamp con risoluzioni diverse. Gli esempi sono millisecondi e microsecondi.

Quando il mapper legge una proprietà di input, la converte in un tipo interno. Questa conversione è necessaria per contenere i dati in memoria fino a quando non viene scritto in un campo di output. La conversione in un tipo interno avviene indipendentemente dal fatto che i formati di serializzazione di input e output siano uguali.

La rappresentazione interna utilizza i tipi di dati seguenti:

Tipo Descrizione
bool True/false logico.
integer Archiviato come intero con segno a 128 bit.
float Archiviato come numero a virgola mobile a 64 bit.
string Stringa UTF-8.
bytes Dati binari, stringa di valori senza segno a 8 bit.
datetime Ora UTC o locale con risoluzione nanosecondo.
time Ora del giorno con risoluzione nanosecondo.
duration Durata con risoluzione nanosecondo.
array Matrice di qualsiasi tipo elencato in precedenza.
map Vettore di coppie (chiave, valore) di qualsiasi tipo elencato in precedenza.

Campi del record di input

Quando un campo di record di input viene letto, il tipo sottostante viene convertito in una di queste varianti di tipo interno. La rappresentazione interna è abbastanza versatile per gestire la maggior parte dei tipi di input con una conversione minima o nessuna. Tuttavia, alcuni tipi di input richiedono la conversione o non sono supportati. Alcuni esempi:

  • Tipo AvroUUID: viene convertito in un string perché non esiste un tipo specifico UUID nella rappresentazione interna.
  • Tipo Avro decimal: non è supportato dal mapper, quindi i campi di questo tipo non possono essere inclusi nei mapping.
  • Tipo Avro duration: la conversione può variare. Se il months campo è impostato, non è supportato. Se solo days e milliseconds sono impostati, viene convertito nella rappresentazione interna duration .

Per alcuni formati, vengono usati i tipi surrogati. Ad esempio, JSON non ha un datetime tipo e archivia datetime invece i valori come stringhe formattate in base a ISO8601. Quando il mapper legge tale campo, la rappresentazione interna rimane una stringa.

Campi dei record di output

Il mapper è progettato per essere flessibile convertendo i tipi interni in tipi di output per supportare scenari in cui i dati provengono da un formato di serializzazione con un sistema di tipi limitato. Gli esempi seguenti illustrano come vengono gestite le conversioni:

  • Tipi numerici: questi tipi possono essere convertiti in altre rappresentazioni, anche se significa perdere precisione. Ad esempio, un numero a virgola mobile a 64 bit (f64) può essere convertito in un intero a 32 bit (i32).
  • Stringhe a numeri: se il record in ingresso contiene una stringa come 123 e il campo di output è un intero a 32 bit, il mapper converte e scrive il valore come numero.
  • Stringhe ad altri tipi:
    • Se il campo di output è datetime, il mapper tenta di analizzare la stringa come ISO8601 formattato datetime.
    • Se il campo di output è binary/bytes, il mapper tenta di deserializzare la stringa da una stringa con codifica base64.
  • Valori booleani:
    • Convertito in 0/1 se il campo di output è numerico.
    • Convertito in true/false se il campo di output è stringa.

Conversioni di tipi esplicite

Sebbene le conversioni automatiche funzionino come previsto in base alle procedure di implementazione comuni, esistono istanze in cui la conversione corretta non può essere determinata automaticamente e genera un errore non supportato . Per risolvere queste situazioni, sono disponibili diverse funzioni di conversione per definire in modo esplicito la modalità di trasformazione dei dati. Queste funzioni offrono un maggiore controllo sul modo in cui i dati vengono convertiti e consentono di mantenere l'integrità dei dati anche quando i metodi automatici non rientrano.

Usare una formula di conversione con tipi

Nei mapping, una formula facoltativa può specificare come vengono elaborati i dati dall'input prima di essere scritti nel campo di output. Se non viene specificata alcuna formula, il mapper copia il campo di input nell'output usando il tipo interno e le regole di conversione.

Se si specifica una formula, i tipi di dati disponibili per l'uso nelle formule sono limitati a:

  • Integer
  • Numeri a virgola mobile
  • Stringhe
  • Valori booleani
  • Matrici dei tipi precedenti
  • Valore mancante

Map e byte non possono partecipare alle formule.

I tipi correlati all'ora (datetime, timee duration) vengono convertiti in valori interi che rappresentano il tempo in secondi. Dopo la valutazione della formula, i risultati vengono archiviati nella rappresentazione interna e non vengono convertiti di nuovo. Ad esempio, datetime convertito in secondi rimane un numero intero. Se il valore verrà usato nei datetime campi, è necessario applicare un metodo di conversione esplicito. Un esempio è la conversione del valore in una stringa ISO8601 che viene convertita automaticamente nel datetime tipo del formato di serializzazione di output.

Usare tipi irregolari

Considerazioni speciali si applicano a tipi come matrici e valore mancante.

Matrici

Le matrici possono essere elaborate usando funzioni di aggregazione per calcolare un singolo valore da più elementi. Ad esempio, usando il record di input:

{
  "Measurements": [2.34, 12.3, 32.4]
}

Con il mapping:

inputs: [
  'Measurements' // - $1
]
output: 'Measurement'
expression: 'min($1)'

Questa configurazione seleziona il valore più piccolo dalla Measurements matrice per il campo di output.

È anche possibile usare funzioni che generano una nuova matrice:

inputs: [
  'Measurements' // - $1
]
output: 'Measurements'
expression: 'take($1, 10)'  // taking at max 10 items

È anche possibile creare matrici da più valori singoli:

inputs: [
  'minimum' // - - $1
  'maximum' // - - $2
  'average' // - - $3
  'mean'    // - - $4
]
output: 'stats'
expression: '($1, $2, $3, $4)'

Questo mapping crea una matrice contenente il valore minimo, massimo, medio e medio.

Valore mancante

Il valore mancante è un tipo speciale usato negli scenari, ad esempio:

  • Gestione dei campi mancanti nell'input fornendo un valore alternativo.
  • Rimozione condizionale di un campo in base alla relativa presenza.

Mapping di esempio che usa un valore mancante:

{
  "Employment": {      
    "Position": "Analyst",
    "BaseSalary": 75000,
    "WorkingHours": "Regular"
  }
}

Il record di input contiene il BaseSalary campo , ma possibilmente facoltativo. Si supponga che, se il campo non è presente, è necessario aggiungere un valore da un set di dati di contestualizzazione:

{
  "Position": "Analyst",
  "BaseSalary": 70000,
  "WorkingHours": "Regular"
}

Un mapping può verificare se il campo è presente nel record di input. Se il campo viene trovato, l'output riceve tale valore esistente. In caso contrario, l'output riceve il valore dal set di dati di contesto. Ad esempio:

inputs: [
  'BaseSalary' // - - - - - - - - - - - $1
  '$context(position).BaseSalary' //  - $2
]
output: 'BaseSalary'
expression: 'if($1 == (), $2, $1)'

conversion usa la funzione if con tre parametri:

  • Il primo parametro è una condizione. Nell'esempio viene verificato se il BaseSalary campo del campo di input (aliasato come $1) è il valore mancante.
  • Il secondo parametro è il risultato della funzione se la condizione nel primo parametro è true. In questo esempio si tratta del campo BaseSalary del set di dati di contestualizzazione (il cui alias è $2).
  • Il terzo parametro è il valore della condizione se il primo parametro è false.

Funzioni disponibili

Le funzioni possono essere usate nella formula di conversione per eseguire varie operazioni:

  • min per selezionare un singolo elemento da un array
  • if per selezionare tra valori
  • Manipolazione delle stringhe (ad esempio, uppercase())
  • Conversione esplicita (ad esempio, ISO8601_datetime)
  • Aggregazione (ad esempio, avg())

Operazioni disponibili

I flussi di dati offrono un'ampia gamma di funzioni di conversione predefinite che consentono agli utenti di eseguire facilmente conversioni di unità senza la necessità di calcoli complessi. Queste funzioni predefinite riguardano conversioni comuni, ad esempio temperatura, pressione, lunghezza, peso e volume. L'elenco seguente mostra le funzioni di conversione disponibili, insieme alle relative formule e nomi di funzione corrispondenti:

Conversione Formula Nome della funzione
Celsius a Fahrenheit F = (C * 9/5) + 32 cToF
DA PSI a barra Bar = PSI * 0.0689476 psiToBar
Da pollice a cm Cm = pollice * 2,54 inToCm
Piedi a contatore Contatore = piede * 0,3048 ftToM
Lbs to kg Kg = lbs * 0,453592 lbToKg
Galloni a litri Litri = galloni * 3,78541 galToL

Oltre a queste conversioni unidirezionali, sono supportati anche i calcoli inversi:

Conversione Formula Nome della funzione
Da Fahrenheit a Celsius C = (F - 32) * 5/9 fToC
Da barra a PSI PSI = bar / 0,0689476 barToPsi
Cm a pollice Pollice = cm / 2,54 cmToIn
Metro a piedi Piede = metro / 0,3048 mToFt
Kg a lbs Lbs = kg / 0,453592 kgToLb
Litri a galloni Galloni = litri / 3,78541 lToGal

Queste funzioni sono progettate per semplificare il processo di conversione. Consentono agli utenti di immettere i valori in un'unità e di ricevere il valore corrispondente in un'altra unità senza sforzo.

È inoltre disponibile una funzione di ridimensionamento per ridimensionare l'intervallo di valori nell'intervallo definito dall'utente. Per l'esempio scale($1,0,10,0,100), il valore di input viene ridimensionato dall'intervallo da 0 a 10 all'intervallo da 0 a 100.

Inoltre, gli utenti hanno la flessibilità di definire le proprie funzioni di conversione usando semplici formule matematiche. Il nostro sistema supporta operatori di base, ad esempio addizione (+), sottrazione (-), moltiplicazione (*) e divisione (/). Questi operatori seguono regole standard di precedenza. Ad esempio, la moltiplicazione e la divisione vengono eseguite prima dell'addizione e della sottrazione. La precedenza può essere modificata usando le parentesi per garantire l'ordine corretto delle operazioni. Questa funzionalità consente agli utenti di personalizzare le conversioni di unità per soddisfare esigenze o preferenze specifiche, migliorando l'utilità complessiva e la versatilità del sistema.

Per calcoli più complessi, sono disponibili anche funzioni come sqrt (che trovano la radice quadrata di un numero).

Operatori aritmetici, di confronto e booleani disponibili raggruppati per precedenza

Operatore Descrizione
^ Elevamento a potenza: $1 ^ 3

Poiché Exponentiation ha la precedenza più alta, viene eseguita per prima, a meno che le parentesi non eseguano l'override di questo ordine:

  • $1 * 2 ^ 3 viene interpretato come $1 * 8 perché la parte 2 ^ 3 viene eseguita per prima, prima della moltiplicazione.
  • ($1 * 2) ^ 3 elabora la moltiplicazione prima dell'esponente.
Operatore Descrizione
- Negazione
! NOT logico

Negation e Logical not hanno una precedenza elevata, quindi si attaccano sempre al loro vicino immediato, tranne quando l'esponente è coinvolto:

  • -$1 * 2 nega $1 prima e quindi moltiplica.
  • -($1 * 2) moltiplica e quindi nega il risultato.
Operatore Descrizione
* Moltiplicazione: $1 * 10
/ Divisione: $1 / 25 (Result è un numero intero se entrambi gli argomenti sono interi, in caso contrario float)
% Modulo: $1 % 25

Multiplication, Divisione Modulo, aventi la stessa precedenza, vengono eseguiti da sinistra a destra, a meno che l'ordine non venga modificato da parentesi.

Operatore Descrizione
+ Aggiunta di valori numerici, concatenazione per le stringhe
- Sottrazione

Addition e Subtraction sono considerate operazioni più deboli rispetto alle operazioni nel gruppo precedente:

  • $1 + 2 * 3$1 + 6 restituisce perché 2 * 3 viene eseguito per primo a causa della precedenza superiore di multiplication.
  • ($1 + 2) * 3assegna priorità prima Multiplicationdi Addition .
Operatore Descrizione
< Minore di
> Maggiore di
<= Minore di o uguale a
>= Maggiore di o uguale a
== Uguale a
!= Diverso da

Comparisons operare su valori numerici, booleani e stringa. Poiché hanno una precedenza inferiore rispetto agli operatori aritmetici, non sono necessarie parentesi per confrontare i risultati in modo efficace:

  • $1 * 2 <= $2 è pari a ($1 * 2) <= $2.
Operatore Descrizione
|| OR logico
&& AND logico

Gli operatori logici vengono usati per concatenare le condizioni:

  • $1 > 100 && $2 > 200