Memetakan data dengan menggunakan aliran data
Penting
Pratinjau Operasi Azure IoT – diaktifkan oleh Azure Arc saat ini dalam pratinjau. Anda tidak boleh menggunakan perangkat lunak pratinjau ini di lingkungan produksi.
Anda harus menyebarkan penginstalan Azure IoT Operations baru saat rilis yang tersedia secara umum tersedia. Anda tidak akan dapat memutakhirkan penginstalan pratinjau.
Untuk persyaratan hukum yang berlaku untuk fitur Azure yang beta, dalam pratinjau, atau belum dirilis ke ketersediaan umum, lihat Ketentuan Penggunaan Tambahan untuk Pratinjau Microsoft Azure.
Gunakan bahasa pemetaan aliran data untuk mengubah data di Operasi Azure IoT. Sintaksnya adalah cara sederhana, namun kuat, untuk menentukan pemetaan yang mengubah data dari satu format ke format lainnya. Artikel ini memberikan gambaran umum tentang bahasa pemetaan aliran data dan konsep utama.
Pemetaan memungkinkan Anda mengubah data dari satu format ke format lainnya. Pertimbangkan catatan input berikut:
{
"Name": "Grace Owens",
"Place of birth": "London, TX",
"Birth Date": "19840202",
"Start Date": "20180812",
"Position": "Analyst",
"Office": "Kent, WA"
}
Bandingkan dengan rekaman output:
{
"Employee": {
"Name": "Grace Owens",
"Date of Birth": "19840202"
},
"Employment": {
"Start Date": "20180812",
"Position": "Analyst, Kent, WA",
"Base Salary": 78000
}
}
Dalam catatan output, perubahan berikut dilakukan pada data rekaman input:
- Bidang diganti namanya: Bidang
Birth Date
sekarangDate of Birth
. - Bidang direstrukturisasi: Keduanya
Name
danDate of Birth
dikelompokkan di bawah kategori baruEmployee
. - Bidang dihapus: Bidang
Place of birth
dihapus karena tidak ada dalam output. - Bidang ditambahkan: Bidang
Base Salary
adalah bidang baru dalamEmployment
kategori. - Nilai bidang diubah atau digabungkan: Bidang
Position
dalam output menggabungkanPosition
bidang danOffice
dari input.
Transformasi dicapai melalui pemetaan, yang biasanya melibatkan:
- Definisi input: Mengidentifikasi bidang dalam rekaman input yang digunakan.
- Definisi output: Menentukan di mana dan bagaimana bidang input diatur dalam rekaman output.
- Konversi (opsional): Memodifikasi bidang input agar pas dengan bidang output.
expression
diperlukan ketika beberapa bidang input digabungkan ke dalam satu bidang output.
Pemetaan berikut adalah contoh:
{
inputs: [
'BirthDate'
]
output: 'Employee.DateOfBirth'
}
{
inputs: [
'Position' // - - - - $1
'Office' // - - - - $2
]
output: 'Employment.Position'
expression: '$1 + ", " + $2'
}
{
inputs: [
'$context(position).BaseSalary'
]
output: 'Employment.BaseSalary'
}
Contoh peta:
- Pemetaan satu-ke-satu:
BirthDate
langsung dipetakan tanpaEmployee.DateOfBirth
konversi. - Pemetaan banyak ke satu: Menggabungkan
Position
danOffice
ke dalam satuEmployment.Position
bidang. Rumus konversi ($1 + ", " + $2
) menggabungkan bidang ini ke dalam string yang diformat. - Data kontekstual:
BaseSalary
ditambahkan dari himpunan data kontekstual bernamaposition
.
Referensi bidang
Referensi bidang menunjukkan cara menentukan jalur dalam input dan output dengan menggunakan notasi titik seperti Employee.DateOfBirth
atau mengakses data dari himpunan data kontekstual melalui $context(position)
.
Properti pengguna MQTT
Saat Anda menggunakan MQTT sebagai sumber atau tujuan, Anda dapat mengakses properti pengguna MQTT dalam bahasa pemetaan. Properti pengguna dapat dipetakan dalam input atau output.
Dalam contoh berikut, properti MQTT topic
dipetakan ke origin_topic
bidang dalam output.
inputs: [
'$metadata.topic'
]
output: 'origin_topic'
Anda juga dapat memetakan properti MQTT ke header output. Dalam contoh berikut, MQTT topic
dipetakan ke origin_topic
bidang di properti pengguna output:
inputs: [
'$metadata.topic'
]
output: '$metadata.user_property.origin_topic'
Pemilih himpunan data kontekstualisasi
Pemilih ini memungkinkan pemetaan untuk mengintegrasikan data tambahan dari database eksternal, yang disebut sebagai himpunan data kontekstualisasi.
Pemfilteran rekaman
Pemfilteran rekaman melibatkan kondisi pengaturan untuk memilih rekaman mana yang harus diproses atau dihilangkan.
Notasi titik
Notasi titik banyak digunakan dalam ilmu komputer untuk mereferensikan bidang, bahkan secara rekursif. Dalam pemrograman, nama bidang biasanya terdiri dari huruf dan angka. Sampel notasi titik standar mungkin terlihat seperti contoh ini:
inputs: [
'Person.Address.Street.Number'
]
Dalam aliran data, jalur yang dijelaskan oleh notasi titik mungkin menyertakan string dan beberapa karakter khusus tanpa perlu melarikan diri:
inputs: [
'Person.Date of Birth'
]
Dalam kasus lain, pelepasan diperlukan:
inputs: [
'Person."Tag.10".Value'
]
Contoh sebelumnya, di antara karakter khusus lainnya, berisi titik-titik dalam nama bidang. Tanpa melarikan diri, nama bidang akan berfungsi sebagai pemisah dalam notasi titik itu sendiri.
Meskipun aliran data menguraikan jalur, aliran data hanya memperlakukan dua karakter sebagai khusus:
- Titik (
.
) bertindak sebagai pemisah bidang. - Tanda kutip tunggal, saat ditempatkan di awal atau akhir segmen, mulai bagian yang lolos di mana titik tidak diperlakukan sebagai pemisah bidang.
Karakter lain diperlakukan sebagai bagian dari nama bidang. Fleksibilitas ini berguna dalam format seperti JSON, di mana nama bidang dapat berupa string arbitrer.
Di Bicep, semua string diapit dalam tanda kutip tunggal ('
). Contoh tentang pengutipan yang tepat dalam YAML untuk penggunaan Kubernetes tidak berlaku.
Melarikan diri
Fungsi utama untuk melarikan diri dalam jalur yang diberi notasi titik adalah untuk mengakomodasi penggunaan titik-titik yang merupakan bagian dari nama bidang daripada pemisah:
inputs: [
'Payload."Tag.10".Value'
]
Dalam contoh ini, jalur terdiri dari tiga segmen: Payload
, , Tag.10
dan Value
.
Aturan pelepasan dalam notasi titik
Keluar dari setiap segmen secara terpisah: Jika beberapa segmen berisi titik-titik, segmen tersebut harus diapit dalam tanda kutip ganda. Segmen lain juga dapat dikutip, tetapi tidak memengaruhi interpretasi jalur:
inputs: [ 'Payload."Tag.10".Measurements."Vibration.$12".Value' ]
Penggunaan tanda kutip ganda yang tepat: Tanda kutip ganda harus membuka dan menutup segmen yang lolos. Tanda kutip apa pun di tengah segmen dianggap sebagai bagian dari nama bidang:
inputs: [ 'Payload.He said: "Hello", and waved' ]
Contoh ini mendefinisikan dua bidang: Payload
dan He said: "Hello", and waved
. Ketika titik muncul dalam keadaan ini, titik terus berfungsi sebagai pemisah:
inputs: [
'Payload.He said: "No. It is done"'
]
Dalam hal ini, jalur dibagi menjadi segmen Payload
, , He said: "No
dan It is done"
(dimulai dengan spasi).
Algoritma segmentasi
- Jika karakter pertama segmen adalah tanda kutip, pengurai mencari tanda kutip berikutnya. String yang diapit di antara tanda kutip ini dianggap sebagai segmen tunggal.
- Jika segmen tidak dimulai dengan tanda kutip, pengurai mengidentifikasi segmen dengan mencari titik berikutnya atau akhir jalur.
Kartubebas
Dalam banyak skenario, rekaman output sangat menyerupai rekaman input, dengan hanya modifikasi kecil yang diperlukan. Saat Anda berurusan dengan rekaman yang berisi banyak bidang, menentukan pemetaan secara manual untuk setiap bidang bisa menjadi melelahkan. Wildcard menyederhanakan proses ini dengan memungkinkan pemetaan umum yang dapat diterapkan secara otomatis ke beberapa bidang.
Mari kita pertimbangkan skenario dasar untuk memahami penggunaan tanda bintang dalam pemetaan:
inputs: [
'*'
]
output: '*'
Berikut adalah cara tanda bintang (*
) beroperasi dalam konteks ini:
- Pencocokan pola: Tanda bintang dapat cocok dengan satu segmen atau beberapa segmen jalur. Ini berfungsi sebagai tempat penampung untuk segmen apa pun di jalur.
- Pencocokan bidang: Selama proses pemetaan, algoritma mengevaluasi setiap bidang dalam rekaman input terhadap pola yang ditentukan dalam
inputs
. Tanda bintang dalam contoh sebelumnya cocok dengan semua jalur yang mungkin, secara efektif pas dengan setiap bidang individu dalam input. - Segmen yang diambil: Bagian jalur yang cocok dengan tanda bintang disebut sebagai
captured segment
. - Pemetaan output: Dalam konfigurasi output,
captured segment
ditempatkan di mana tanda bintang muncul. Ini berarti bahwa struktur input dipertahankan dalam output, dengancaptured segment
mengisi tempat penampung yang disediakan oleh tanda bintang.
Konfigurasi ini menunjukkan bentuk pemetaan yang paling umum, di mana setiap bidang dalam input langsung dipetakan ke bidang yang sesuai dalam output tanpa modifikasi.
Contoh lain menggambarkan bagaimana kartubebas dapat digunakan untuk mencocokkan subbagian dan memindahkannya bersama-sama. Contoh ini secara efektif meratakan struktur berlapis dalam objek JSON.
JSON asli:
{
"ColorProperties": {
"Hue": "blue",
"Saturation": "90%",
"Brightness": "50%",
"Opacity": "0.8"
},
"TextureProperties": {
"type": "fabric",
"SurfaceFeel": "soft",
"SurfaceAppearance": "matte",
"Pattern": "knitted"
}
}
Konfigurasi pemetaan yang menggunakan wildcard:
{
inputs: [
'ColorProperties.*'
]
output: '*'
}
{
inputs: [
'TextureProperties.*'
]
output: '*'
}
Hasil JSON:
{
"Hue": "blue",
"Saturation": "90%",
"Brightness": "50%",
"Opacity": "0.8",
"type": "fabric",
"SurfaceFeel": "soft",
"SurfaceAppearance": "matte",
"Pattern": "knitted"
}
Penempatan kartubebas
Saat Anda menempatkan kartubebas, Anda harus mengikuti aturan ini:
- Tanda bintang tunggal per dataDestination: Hanya satu tanda bintang (
*
) yang diizinkan dalam satu jalur. - Pencocokan segmen penuh: Tanda bintang harus selalu cocok dengan seluruh segmen jalur. Ini tidak dapat digunakan untuk mencocokkan hanya sebagian dari segmen, seperti
path1.partial*.path3
. - Posisi: Tanda bintang dapat diposisikan di berbagai bagian dari
dataDestination
:- Di awal:
*.path2.path3
- Di sini, tanda bintang cocok dengan segmen apa pun yang mengarah kepath2.path3
. - Di tengah:
path1.*.path3
- Dalam konfigurasi ini, tanda bintang cocok dengan segmen apa pun antarapath1
danpath3
. - Di akhir:
path1.path2.*
- Tanda bintang di akhir cocok dengan segmen apa pun yang mengikuti setelahpath1.path2
.
- Di awal:
- Jalur yang berisi tanda bintang harus diapit dalam tanda kutip tunggal (
'
).
Kartubebas multi-input
JSON asli:
{
"Saturation": {
"Max": 0.42,
"Min": 0.67,
},
"Brightness": {
"Max": 0.78,
"Min": 0.93,
},
"Opacity": {
"Max": 0.88,
"Min": 0.91,
}
}
Konfigurasi pemetaan yang menggunakan wildcard:
inputs: [
'*.Max' // - $1
'*.Min' // - $2
]
output: 'ColorProperties.*'
expression: '($1 + $2) / 2'
Hasil JSON:
{
"ColorProperties" : {
"Saturation": 0.54,
"Brightness": 0.85,
"Opacity": 0.89
}
}
Jika Anda menggunakan wildcard multi-input, tanda bintang (*
) harus secara konsisten mewakili hal yang sama Captured Segment
di setiap input. Misalnya, ketika *
mengambil dalam pola *.Max
, algoritma pemetaan mengharapkan yang sesuai untuk dicocokkan Saturation.Min
dengan pola *.Min
Saturation
. Di sini, *
digantikan oleh Captured Segment
dari input pertama, memandu pencocokan untuk input berikutnya.
Pertimbangkan contoh terperinci ini:
JSON asli:
{
"Saturation": {
"Max": 0.42,
"Min": 0.67,
"Mid": {
"Avg": 0.51,
"Mean": 0.56
}
},
"Brightness": {
"Max": 0.78,
"Min": 0.93,
"Mid": {
"Avg": 0.81,
"Mean": 0.82
}
},
"Opacity": {
"Max": 0.88,
"Min": 0.91,
"Mid": {
"Avg": 0.89,
"Mean": 0.89
}
}
}
Konfigurasi pemetaan awal yang menggunakan wildcard:
inputs: [
'*.Max' // - $1
'*.Min' // - $2
'*.Avg' // - $3
'*.Mean' // - $4
]
Pemetaan awal ini mencoba membangun array (misalnya, untuk Opacity
: [0.88, 0.91, 0.89, 0.89]
). Konfigurasi ini gagal karena:
- Input
*.Max
pertama menangkap segmen sepertiSaturation
. - Pemetaan mengharapkan input berikutnya hadir pada tingkat yang sama:
Saturation.Max
Saturation.Min
Saturation.Avg
Saturation.Mean
Karena Avg
dan Mean
ditumpuk dalam Mid
, tanda bintang dalam pemetaan awal tidak menangkap jalur ini dengan benar.
Konfigurasi pemetaan yang dikoreksi:
inputs: [
'*.Max' // - $1
'*.Min' // - $2
'*.Mid.Avg' // - $3
'*.Mid.Mean' // - $4
]
Pemetaan yang direvisi ini secara akurat menangkap bidang yang diperlukan. Ini menentukan jalur dengan benar untuk menyertakan objek berlapis Mid
, yang memastikan bahwa tanda bintang bekerja secara efektif di berbagai tingkat struktur JSON.
Aturan kedua vs. spesialisasi
Saat Anda menggunakan contoh sebelumnya dari wildcard multi-input, pertimbangkan pemetaan berikut yang menghasilkan dua nilai turunan untuk setiap properti:
{
inputs: [
'*.Max' // - $1
'*.Min' // - $2
]
output: 'ColorProperties.*.Avg'
expression: '($1 + $2) / 2'
}
{
inputs: [
'*.Max' // - $1
'*.Min' // - $2
]
output: 'ColorProperties.*.Diff'
expression: 'abs($1 - $2)'
}
Pemetaan ini dimaksudkan untuk membuat dua perhitungan terpisah (Avg
dan Diff
) untuk setiap properti di bawah ColorProperties
. Contoh ini menunjukkan hasilnya:
{
"ColorProperties": {
"Saturation": {
"Avg": 0.54,
"Diff": 0.25
},
"Brightness": {
"Avg": 0.85,
"Diff": 0.15
},
"Opacity": {
"Avg": 0.89,
"Diff": 0.03
}
}
}
Di sini, definisi pemetaan kedua pada input yang sama bertindak sebagai aturan kedua untuk pemetaan.
Sekarang, pertimbangkan skenario di mana bidang tertentu memerlukan perhitungan yang berbeda:
{
inputs: [
'*.Max' // - $1
'*.Min' // - $2
]
output: 'ColorProperties.*'
expression: '($1 + $2) / 2'
}
{
inputs: [
'Opacity.Max' // - $1
'Opacity.Min' // - $2
]
output: 'ColorProperties.OpacityAdjusted'
expression: '($1 + $2 + 1.32) / 2'
}
Dalam hal ini, Opacity
bidang memiliki perhitungan unik. Dua opsi untuk menangani skenario yang tumpang tindih ini adalah:
- Sertakan kedua pemetaan untuk
Opacity
. Karena bidang output berbeda dalam contoh ini, bidang tersebut tidak akan saling menimpa. - Gunakan aturan yang lebih spesifik untuk
Opacity
dan hapus aturan yang lebih umum.
Pertimbangkan kasus khusus untuk bidang yang sama untuk membantu memutuskan tindakan yang tepat:
{
inputs: [
'*.Max' // - $1
'*.Min' // - $2
]
output: 'ColorProperties.*'
expression: '($1 + $2) / 2'
}
{
inputs: [
'Opacity.Max' // - $1
'Opacity.Min' // - $2
]
}
Bidang kosong output
dalam definisi kedua menyiratkan tidak menulis bidang dalam rekaman output (secara efektif menghapus Opacity
). Penyiapan ini lebih dari satu Specialization
dari .Second Rule
Resolusi pemetaan yang tumpang tindih menurut aliran data:
- Evaluasi berlangsung dari aturan teratas dalam definisi pemetaan.
- Jika pemetaan baru diselesaikan ke bidang yang sama dengan aturan sebelumnya, kondisi berikut berlaku:
Rank
dihitung untuk setiap input yang diselesaikan berdasarkan jumlah segmen yang diambil kartubebas. Misalnya, jikaCaptured Segments
adalahProperties.Opacity
,Rank
adalah 2. Jika hanyaOpacity
,Rank
adalah 1. Pemetaan tanpa kartubebas memilikiRank
0.Rank
Jika aturan terakhir sama dengan atau lebih tinggi dari aturan sebelumnya, aliran data memperlakukannya sebagaiSecond Rule
.- Jika tidak, aliran data memperlakukan konfigurasi sebagai
Specialization
.
Misalnya, pemetaan yang mengarahkan Opacity.Max
dan Opacity.Min
ke output kosong memiliki Rank
0. Karena aturan kedua memiliki yang lebih rendah Rank
dari yang sebelumnya, aturan tersebut dianggap sebagai spesialisasi dan mengambil alih aturan sebelumnya, yang akan menghitung nilai untuk Opacity
.
Kartubebas dalam himpunan data kontekstualisasi
Sekarang, mari kita lihat bagaimana himpunan data kontekstualisasi dapat digunakan dengan kartubebas melalui contoh. Pertimbangkan himpunan data bernama position
yang berisi catatan berikut:
{
"Position": "Analyst",
"BaseSalary": 70000,
"WorkingHours": "Regular"
}
Dalam contoh sebelumnya, kami menggunakan bidang tertentu dari himpunan data ini:
inputs: [
'$context(position).BaseSalary'
]
output: 'Employment.BaseSalary'
Pemetaan ini menyalin BaseSalary
dari himpunan data konteks langsung ke bagian Employment
rekaman output. Jika Anda ingin mengotomatiskan proses dan menyertakan semua bidang dari himpunan position
data ke dalam Employment
bagian , Anda dapat menggunakan kartubebas:
inputs: [
'$context(position).*'
]
output: 'Employment.*'
Konfigurasi ini memungkinkan pemetaan dinamis di mana setiap bidang dalam himpunan position
data disalin ke bagian Employment
rekaman output:
{
"Employment": {
"Position": "Analyst",
"BaseSalary": 70000,
"WorkingHours": "Regular"
}
}
Nilai terakhir diketahui
Anda dapat melacak nilai properti terakhir yang diketahui. Akhiri bidang input dengan ? $last
untuk mengambil nilai bidang terakhir yang diketahui. Ketika properti kehilangan nilai dalam payload input berikutnya, nilai terakhir yang diketahui dipetakan ke payload output.
Misalnya, pertimbangkan pemetaan berikut:
inputs: [
'Temperature ? $last'
]
output: 'Thermostat.Temperature'
Dalam contoh ini, nilai terakhir yang Temperature
diketahui dilacak. Jika payload input berikutnya tidak berisi Temperature
nilai, nilai terakhir yang diketahui digunakan dalam output.