Bahasa kueri Hub IoT untuk perangkat dan modul kembar, pekerjaan, dan perutean pesan

IoT Hub menyediakan bahasa seperti SQL yang kuat untuk mengambil informasi mengenai devive twins, module twins,tugas, dan perutean pesan. Artikel ini menyajikan:

  • Pengenalan fitur utama bahasa kueri IoT Hub, dan
  • Deskripsi terperinci tentang bahasa tersebut. Detail tentang bahasa kueri untuk perutean pesan, lihat kueri dalam perutean pesan.

Catatan

Beberapa fitur yang disebutkan dalam artikel ini, seperti pesan cloud-ke-perangkat, kembar perangkat, dan manajemen perangkat, hanya tersedia di tingkat standar IoT Hub. Untuk mengetahui informasi selengkapnya tentang tingkat IoT Hub standar dan dasar, lihat Cara memilih tingkat IoT Hub yang tepat.

Kueri device dan module twin

Device twins dan module twins dapat mengandung objek JSON arbitrer sebagai tag dan properti. IoT Hub memungkinkan Anda untuk meminta device twins dan module twins sebagai satu dokumen JSON yang berisi semua informasi kembar.

Asumsikan, misalnya, bahwa kembar perangkat hub IoT Anda memiliki struktur berikut (modul twin akan mirip hanya dengan tambahan moduleId):

{
    "deviceId": "myDeviceId",
    "etag": "AAAAAAAAAAc=",
    "status": "enabled",
    "statusUpdateTime": "0001-01-01T00:00:00",
    "connectionState": "Disconnected",
    "lastActivityTime": "0001-01-01T00:00:00",
    "cloudToDeviceMessageCount": 0,
    "authenticationType": "sas",
    "x509Thumbprint": {
        "primaryThumbprint": null,
        "secondaryThumbprint": null
    },
    "version": 2,
    "tags": {
        "location": {
            "region": "US",
            "plant": "Redmond43"
        }
    },
    "properties": {
        "desired": {
            "telemetryConfig": {
                "configId": "db00ebf5-eeeb-42be-86a1-458cccb69e57",
                "sendFrequencyInSecs": 300
            },
            "$metadata": {
            ...
            },
            "$version": 4
        },
        "reported": {
            "connectivity": {
                "type": "cellular"
            },
            "telemetryConfig": {
                "configId": "db00ebf5-eeeb-42be-86a1-458cccb69e57",
                "sendFrequencyInSecs": 300,
                "status": "Success"
            },
            "$metadata": {
            ...
            },
            "$version": 7
        }
    }
}

Kueri kembar perangkat

IoT Hub mengekspos perangkat kembar sebagai koleksi dokumen yang disebut perangkat. Misalnya, kueri berikut mengambil seluruh paket rangkaian kembar:

SELECT * FROM devices

Catatan

Azure IoT SDKs mendukung hasil penomoran yang besar.

Agregasi didukung. Misalnya, kueri berikut mendapatkan hitungan jumlah total perangkat di hub IoT:

SELECT COUNT() as totalNumberOfDevices FROM devices

IoT Hub memungkinkan Anda untuk mengambil pemfilteran kembar perangkat dengan kondisi sewenang-wenang. Misalnya, untuk menerima perangkat kembar di mana tag location.region diatur ke AS gunakan kueri berikut:

SELECT * FROM devices
WHERE tags.location.region = 'US'

Operator Boolean dan perbandingan aritmatika juga didukung. Misalnya, untuk mengambil perangkat kembar yang terletak di AS dan dikonfigurasi untuk mengirim telemetri kurang dari setiap menit, gunakan kueri berikut:

SELECT * FROM devices
  WHERE tags.location.region = 'US'
    AND properties.reported.telemetryConfig.sendFrequencyInSecs >= 60

Sebagai kenyamanan, dimungkinkan juga untuk menggunakan konstanta tetap dengan operator INdan NIN (tidak in). Misalnya, untuk mengambil perangkat kembar yang melaporkan WiFi atau konektivitas kabel menggunakan kueri berikut:

SELECT * FROM devices
  WHERE properties.reported.connectivity IN ['wired', 'wifi']

Seringkali perlu mengidentifikasi semua kembar perangkat yang berisi properti tertentu. IoT Hub mendukung fungsi untuk is_defined() tujuan ini. Misalnya, untuk mengambil perangkat kembar yang menentukan connectivity properti menggunakan kueri berikut:

SELECT * FROM devices
  WHERE is_defined(properties.reported.connectivity)

Lihat bagian klausa WHERE untuk referensi lengkap kemampuan pemfilteran.

Pengelompokan juga didukung. Contohnya, untuk menemukan jumlah perangkat di setiap status konfigurasi telemetri, gunakan kueri berikut:

SELECT properties.reported.telemetryConfig.status AS status,
    COUNT() AS numberOfDevices
  FROM devices
  GROUP BY properties.reported.telemetryConfig.status

Kueri pengelompokan ini akan menjalankan hasil yang mirip dengan contoh berikut:

[
    {
        "numberOfDevices": 3,
        "status": "Success"
    },
    {
        "numberOfDevices": 2,
        "status": "Pending"
    },
    {
        "numberOfDevices": 1,
        "status": "Error"
    }
]

Dalam contoh ini, tiga perangkat melaporkan konfigurasi yang berhasil, dua masih menerapkan konfigurasi, dan satu melaporkan kesalahan.

Kueri proyeksi memungkinkan pengembang untuk menjalankan hanya properti yang mereka pedulikan. Misalnya, untuk mengambil waktu aktivitas terakhir bersama dengan ID perangkat dari semua perangkat yang diaktifkan yang terputus, gunakan kueri berikut:

SELECT DeviceId, LastActivityTime FROM devices WHERE status = 'enabled' AND connectionState = 'Disconnected'

Berikut adalah contoh hasil kueri itu di Query Explorer untuk IoT Hub:

[
  {
    "deviceId": "AZ3166Device",
    "lastActivityTime": "2021-05-07T00:50:38.0543092Z"
  }
]

Modul kueri kembar

Kueri pada modul kembar mirip dengan kueri pada perangkat kembar, tetapi menggunakan koleksi / namespace yang berbeda; alih-alih dari perangkat, Anda meminta dari devices.modules:

SELECT * FROM devices.modules

Kami tidak mengizinkan bergabung antara koleksi perangkat dan devices.modules. Jika Anda ingin mengkueri modul kembar di seluruh perangkat, Anda melakukannya berdasarkan tag. Kueri ini akan menjalankan semua kembar modul di semua perangkat dengan status pemindaian:

SELECT * FROM devices.modules WHERE properties.reported.status = 'scanning'

Kueri ini akan menjalankan semua item kembar modul dengan status pemindaian, tetapi hanya pada subset perangkat yang ditentukan:

SELECT * FROM devices.modules
  WHERE properties.reported.status = 'scanning'
  AND deviceId IN ['device1', 'device2']

C# contoh

Fungsionalitas kueri diekspos oleh SDK layanan C# di kelas RegistryManager.

Berikut adalah contoh kueri sederhana:

var query = registryManager.CreateQuery("SELECT * FROM devices", 100);
while (query.HasMoreResults)
{
    var page = await query.GetNextAsTwinAsync();
    foreach (var twin in page)
    {
        // do work on twin object
    }
}

Objek kueri di-instantiated dengan ukuran halaman (hingga 100). Kemudian beberapa halaman diambil dengan memanggil metode GetNextAsTwinAsync beberapa kali.

Objek kueri memaparkan beberapa nilai Berikutnya, bergantung pada opsi deserialisasi yang diperlukan oleh kueri. Misalnya, perangkat twin atau objek pekerjaan, atau JSON biasa saat menggunakan proyeksi.

Node.js contoh

Fungsionalitas kueri diekspos oleh SDK layanan Azure IoT untuk Node.js di objek Registri.

Berikut adalah contoh kueri sederhana:

var query = registry.createQuery('SELECT * FROM devices', 100);
var onResults = function(err, results) {
    if (err) {
        console.error('Failed to fetch the results: ' + err.message);
    } else {
        // Do something with the results
        results.forEach(function(twin) {
            console.log(twin.deviceId);
        });

        if (query.hasMoreResults) {
            query.nextAsTwin(onResults);
        }
    }
};
query.nextAsTwin(onResults);

Objek kueri di-instantiated dengan ukuran halaman (hingga 100). Kemudian beberapa halaman diambil dengan memanggil metodeAsTwin berikutnya beberapa kali.

Objek kueri memaparkan beberapa nilai Berikutnya, bergantung pada opsi deserialisasi yang diperlukan oleh kueri. Misalnya, perangkat twin atau objek pekerjaan, atau JSON biasa saat menggunakan proyeksi.

Batasan

Penting

Hasil kueri dapat memiliki beberapa menit penundaan sehubungan dengan nilai terbaru dalam kembar perangkat. Jika mengkueri masing-masing perangkat kembar berdasarkan ID, gunakan get twin REST API. API ini selalu menjalankan nilai terbaru dan memiliki batas throttling yang lebih tinggi. Anda dapat mengeluarkan REST API secara langsung atau menggunakan fungsionalitas yang setara di salah satu SDK Layanan Azure IoT Hub.

Saat ini, perbandingan hanya didukung antara jenis primitif (tanpa objek), misalnya ... WHERE properties.desired.config = properties.reported.config hanya didukung jika properti tersebut memiliki nilai primitif.

Mulai menggunakan kueri pekerjaan

Jobs menyediakan cara untuk menjalankan operasi di set perangkat. Setiap kembar perangkat berisi informasi pekerjaan yang merupakan bagian dari koleksi yang disebut pekerjaan.

{
    "deviceId": "myDeviceId",
    "etag": "AAAAAAAAAAc=",
    "tags": {
        ...
    },
    "properties": {
        ...
    },
    "jobs": [
        {
            "deviceId": "myDeviceId",
            "jobId": "myJobId",
            "jobType": "scheduleTwinUpdate",
            "status": "completed",
            "startTimeUtc": "2016-09-29T18:18:52.7418462",
            "endTimeUtc": "2016-09-29T18:20:52.7418462",
            "createdDateTimeUtc": "2016-09-29T18:18:56.7787107Z",
            "lastUpdatedDateTimeUtc": "2016-09-29T18:18:56.8894408Z",
            "outcome": {
                "deviceMethodResponse": null
            }
        },
        ...
    ]
}

Saat ini, koleksi ini dapat dikueri devices.jobs dalam bahasa kueri IoT Hub.

Penting

Saat ini, properti pekerjaan tidak pernah dijalankan ketika meminta perangkat kembar. Artinya, kueri yang berisi 'perangkat FROM'. Properti pekerjaan hanya dapat diakses langsung dengan kueri menggunakan FROM devices.jobs.

Misalnya, untuk mendapatkan semua pekerjaan (lewat dan terjadwal) yang memengaruhi satu perangkat, Anda bisa menggunakan kueri berikut:

SELECT * FROM devices.jobs
  WHERE devices.jobs.deviceId = 'myDeviceId'

Perhatikan bagaimana kueri ini menyediakan status khusus perangkat (dan mungkin respons metode langsung) dari setiap pekerjaan yang dijalankan.

Dimungkinkan juga untuk menyaring dengan kondisi Boolean sewenang-wenang pada semua properti objek di devices.jobs ini.

Misalnya, untuk mengambil semua pekerjaan pembaruan kembar perangkat yang selesai yang dibuat setelah September 2016 untuk perangkat tertentu, gunakan kueri berikut:

SELECT * FROM devices.jobs
  WHERE devices.jobs.deviceId = 'myDeviceId'
    AND devices.jobs.jobType = 'scheduleTwinUpdate'
    AND devices.jobs.status = 'completed'
    AND devices.jobs.createdTimeUtc > '2016-09-01'

Anda juga dapat mengambil hasil per perangkat dari satu pekerjaan.

SELECT * FROM devices.jobs
  WHERE devices.jobs.jobId = 'myJobId'

Batasan

Saat ini, kueri devices.jobs anda tidak mendukung:

  • Proyeksi, oleh karena itu SELECT * hanya mungkin.
  • Kondisi yang mengacu pada perangkat twin selain properti pekerjaan (lihat bagian sebelumnya).
  • Melakukan agregasi, seperti menghitung, membalas, mengelompokkan menurut.

Dasar-dasar kueri IoT Hub

Setiap kueri IoT Hub terdiri dari klausa SELECT dan FROM, dengan klausa WHERE dan GROUP BY opsional. Setiap kueri dijalankan pada kumpulan dokumen JSON, misalnya kembar perangkat. Klausa FROM menunjukkan pengumpulan dokumen akan di-iterasi pada (perangkat,devices.modules, atau devices.jobs). Kemudian, filter dalam klausa WHERE diterapkan. Dengan agregasi, hasil langkah ini dikelompokkan seperti yang ditentukan dalam klausa GROUP BY. Untuk setiap grup, baris dihasilkan seperti yang ditentukan dalam klausa SELECT.

SELECT <select_list>
  FROM <from_specification>
  [WHERE <filter_condition>]
  [GROUP BY <group_specification>]

Klausul FROM

Klausa FROM <from_specification> hanya dapat mengasumsikan tiga nilai: FROM devices untuk menanyakan kembar perangkat, FROM devices.modules untuk menanyakan kembar modul, atau FROM devices.jobs untuk menanyakan detail pekerjaan per perangkat.

Klausul WHERE

Klausa WHERE <filter_condition> bersifat opsional. Ini menentukan satu atau beberapa kondisi yang harus disertakan oleh dokumen JSON dalam koleksi FROM untuk dimasukkan sebagai bagian dari hasil. Setiap dokumen JSON harus mengevaluasi kondisi yang ditentukan menjadi "true" untuk disertakan dalam hasilnya.

Kondisi yang diperbolehkan dijelaskan di bagian Ekspresi dan kondisi.

PILIH klausa

SELECT <select_list> bersifat wajib dan menentukan nilai yang diambil dari kueri. Ini menentukan nilai JSON yang akan digunakan untuk menghasilkan objek JSON baru. Untuk setiap elemen subset yang difilter (dan dikelompokkan secara opsional) dari koleksi FROM, fase proyeksi menghasilkan objek JSON baru. Objek ini dibuat dengan nilai yang ditentukan dalam klausa SELECT.

Berikut ini adalah tata bahasa klausa SELECT:

SELECT [TOP <max number>] <projection list>

<projection_list> ::=
    '*'
    | <projection_element> AS alias [, <projection_element> AS alias]+

<projection_element> :==
    attribute_name
    | <projection_element> '.' attribute_name
    | <aggregate>

<aggregate> :==
    count()
    | avg(<projection_element>)
    | sum(<projection_element>)
    | min(<projection_element>)
    | max(<projection_element>)

Attribute_name mengacu pada properti dokumen JSON apa pun dalam koleksi FROM. Beberapa contoh klausa SELECT dapat ditemukan di bagian Memulai dengan kueri kembar perangkat.

Saat ini, klausa pemilihan yang berbeda dari SELECT* hanya didukung dalam kueri agregat pada kembar perangkat.

klausa GROUP BY

Klausa GROUP BY <group_specification> adalah langkah opsional yang dijalankan setelah filter yang ditentukan dalam klausa WHERE, dan sebelum proyeksi yang ditentukan dalam SELECT. Ini mendokumentasikan dokumen berdasarkan nilai atribut. Grup ini digunakan untuk menghasilkan nilai agregat seperti yang ditentukan dalam klausa SELECT.

Contoh kueri menggunakan GROUP BY adalah:

SELECT properties.reported.telemetryConfig.status AS status,
    COUNT() AS numberOfDevices
FROM devices
GROUP BY properties.reported.telemetryConfig.status

Sintaks formal untuk GROUP BY adalah:

GROUP BY <group_by_element>
<group_by_element> :==
    attribute_name
    | < group_by_element > '.' attribute_name

Attribute_name mengacu pada properti dokumen JSON apa pun dalam koleksi FROM.

Saat ini, klausa GROUP BY hanya didukung saat mengkueri kembar perangkat.

Penting

Istilah ini group saat ini diperlakukan sebagai kata kunci khusus dalam kueri. Jika, Anda menggunakan group sebagai nama properti Anda, pertimbangkan untuk mengelilinginya dengan tanda kurung ganda untuk menghindari kesalahan, misalnya, SELECT * FROM devices WHERE tags.[[group]].name = 'some_value'.

Ekspresi dan kondisi

Pada tingkat tinggi, ekspresi:

  • Mengevaluasi ke contoh tipe JSON (seperti Boolean, angka, string, array, atau objek).
  • Didefinisikan dengan memanipulasi data yang berasal dari perangkat dokumen dan konstanta JSON menggunakan operator dan fungsi bawaan.

Kondisi adalah ekspresi yang mengevaluasi ke Boolean. Setiap konstanta yang berbeda dari Boolean benar dianggap sebagai palsu. Aturan ini mencakup null, tidak terdefinisi, objek atau instans array apa pun, string apa pun, dan Boolean palsu.

Sintaks untuk ekspresi adalah:

<expression> ::=
    <constant> |
    attribute_name |
    <function_call> |
    <expression> binary_operator <expression> |
    <create_array_expression> |
    '(' <expression> ')'

<function_call> ::=
    <function_name> '(' expression ')'

<constant> ::=
    <undefined_constant>
    | <null_constant>
    | <number_constant>
    | <string_constant>
    | <array_constant>

<undefined_constant> ::= undefined
<null_constant> ::= null
<number_constant> ::= decimal_literal | hexadecimal_literal
<string_constant> ::= string_literal
<array_constant> ::= '[' <constant> [, <constant>]+ ']'

Untuk memahami apa yang menjadi kepanjangan dari setiap simbol dalam sintaks ekspresi, lihat tabel berikut:

Simbol Definisi
Nama atribut Properti dokumen JSON apa pun dalam koleksi FROM.
binary_operator Setiap operator biner yang tercantum di bagian Operator.
Nama fungsi Setiap fungsi yang tercantum di bagian Fungsi.
decimal_literal Sebuah pelampung yang dinyatakan dalam notasi desimal.
hexadecimal_literal Angka yang dinyatakan oleh string '0x' diikuti oleh serangkaian digit heksadesimal.
string_literal Untai harfiah adalah untai Unicode yang diwakili oleh urutan nol atau lebih karakter Unicode atau urutan escape. Literal string diapit dalam tanda kutip tunggal atau tanda kutip ganda. Pelarian yang diizinkan: \', \", \\, \uXXXX untuk karakter Unicode yang didefinisikan oleh 4 digit heksadesimal.

Operator

Operator berikut didukung:

Keluarga Operator
Aritmatika +, -, *, /, %
Logis AND, OR, NOT
Perbandingan =, !=, <, >, <=, >=, <>

Fungsi

Saat mengkueri kembar dan pekerjaan, satu-satunya fungsi yang didukung adalah:

Fungsi Deskripsi
IS_DEFINED (properti) Menjalankan Boolean yang menunjukkan apakah properti telah diberi nilai (termasuk null).

Dalam kondisi rute, fungsi matematika berikut didukung:

Fungsi Deskripsi
ABS(x) Mengembalikan nilai absolut (positif) dari ekspresi numerik yang ditentukan.
EXP(x) Menjalankan nilai eksponensial dari ekspresi numerik yang ditentukan (e^x).
POWER(x,y) Menjalankan nilai ekspresi yang ditentukan ke daya yang ditentukan (x^y).
SQUARE(x) Menjalankan kuadrat dari nilai numerik yang ditentukan.
CEILING(x) Menjalankan nilai bilangan bulat terkecil yang lebih besar dari, atau sama dengan ekspresi numerik yang ditentukan.
FLOOR(x) Menjalankan bilangan bulat terbesar yang kurang dari atau sama dengan ekspresi numerik yang ditentukan.
TANDA(x) Menjalankan tanda positif (+1), nol (0), atau negatif (-1) dari ekspresi numerik yang ditentukan.
SQRT(x) Menjalankan akar kuadrat dari nilai numerik yang ditentukan.

Dalam kondisi rute, fungsi pemeriksaan dan pengecoran tipe berikut didukung:

Fungsi Deskripsi
NOMOR AS Mengonversi string input menjadi angka. noop jika input adalah angka; Undefined jika string tidak mewakili angka.
IS_ARRAY Menjalankan nilai Boolean yang menunjukkan jika jenis ekspresi yang ditentukan adalah array.
IS_BOOL Menjalankan nilai Boolean yang menunjukkan jika jenis ekspresi yang ditentukan adalah Boolean.
IS_DEFINED Menjalankan Boolean yang menunjukkan apakah properti telah diberi nilai. Ini hanya didukung ketika nilainya adalah tipe primitif. Jenis primitif termasuk string, Boolean, numerik, atau null. DateTime, tipe objek dan array tidak didukung.
IS_NULL Mengembalikan nilai Boolean yang menunjukkan jika jenis ekspresi yang ditentukan adalah nol.
IS_NUMBER Menjalankan nilai Boolean yang mengindikasikan jenis ekspresi yang ditentukan merupakan angka.
IS_OBJECT Menjalankan nilai Boolean yang mengindikasikan jika jenis ekspresi yang ditentukan adalah objek JSON.
IS_PRIMITIVE Menjalankan nilai Boolean yang menunjukkan apakah tipe ekspresi yang ditentukan adalah primitif (string, Boolean, numerik, atau null ).
IS_STRING Menjalankan nilai Boolean yang mengindikasikan apakah jenis ekspresi yang ditentukan merupakan suatu untai (karakter).

Dalam kondisi rute, fungsi string berikut didukung:

Fungsi Deskripsi
CONCAT(x, y, …) Menjalankan string yang merupakan hasil penggabungan dua atau beberapa nilai string.
PANJANG(x) Menjalankan jumlah karakter dari ekspresi string yang ditentukan.
LEBIH RENDAH(x) Menjalankan ekspresi string setelah mengonversi data karakter huruf kecil menjadi huruf besar.
UPPER(x) Mengembalikan ekspresi string setelah mengonversi data karakter huruf kecil menjadi huruf besar.
SUBSTRING(string, mulai [, panjang]) Menjalankan bagian dari ekspresi untai yang dimulai pada posisi berbasis nol karakter yang ditentukan, dan berlanjut ke panjang yang ditentukan, atau ke akhir untai.
INDEX_OF(string, fragmen) Menjalankan posisi awal kemunculan pertama ekspresi untai (karakter) kedua dalam ekspresi untai (karakter) pertama yang ditentukan, atau -1 jika untai (karakter) tidak ditemukan.
STARTS_WITH(x, y) Menjalankan Boolean yang menunjukkan apakah ekspresi string pertama dimulai dengan yang kedua.
ENDS_WITH(x, y) Menjalankan Boolean yang menunjukkan apakah ekspresi untai (karakter) pertama berakhir dengan yang kedua.
CONTAINS(x,y) Mengembalikan Boolean yang menunjukkan apakah ekspresi string pertama berisi yang kedua.

Langkah berikutnya

Pelajari cara menjalankan kueri di aplikasi Anda menggunakan Azure IoT SDK.