Analisis jenis data kompleks di Azure Synapse Analytics

Artikel ini relevan untuk file dan kontainer Parquet di Azure Synapse Link untuk Azure Cosmos DB. Anda dapat menggunakan Spark atau SQL untuk membaca atau mengubah data dengan skema kompleks seperti array atau struktur berlapis. Contoh berikut dilengkapi dengan satu dokumen, tetapi dapat dengan mudah menskalakan hingga miliaran dokumen dengan Spark atau SQL. Kode yang disertakan dalam artikel ini menggunakan PySpark (Python).

Kasus penggunaan

Jenis data yang kompleks semakin umum dan merupakan tantangan bagi insinyur data. Menganalisis skema dan array berlapis dapat melibatkan kueri SQL yang memakan waktu dan kompleks. Selain itu, mungkin sulit untuk mengganti nama atau memilah jenis data kolom berlapis. Selain itu, ketika Anda bekerja dengan objek yang berlapis dalam, Anda dapat mengalami masalah kinerja.

Insinyur data perlu memahami cara memproses jenis data yang kompleks secara efisien dan membuatnya mudah diakses oleh semua orang. Dalam contoh berikut, Anda menggunakan Spark di Azure Synapse Analytics untuk membaca dan mengubah objek menjadi struktur datar melalui bingkai data. Anda menggunakan model SQL tanpa server di Azure Synapse Analytics untuk mengkueri objek tersebut secara langsung, dan mengembalikan hasilnya sebagai tabel biasa.

Apa itu array dan struktur berlapis?

Objek berikut berasal dari Application Insights. Dalam objek ini, terdapat struktur dan array berlapis yang mengandung struktur berlapis.

{
    "id": "66532691-ab20-11ea-8b1d-936b3ec64e54",
    "context": {
        "data": {
            "eventTime": "2020-06-10T13:43:34.553Z",
            "samplingRate": "100.0",
            "isSynthetic": "false"
        },
        "session": {
            "isFirst": "false",
            "id": "38619c14-7a23-4687-8268-95862c5326b1"
        },
        "custom": {
            "dimensions": [
                {
                    "customerInfo": {
                        "ProfileType": "ExpertUser",
                        "RoomName": "",
                        "CustomerName": "diamond",
                        "UserName": "XXXX@yahoo.com"
                    }
                },
                {
                    "customerInfo": {
                        "ProfileType": "Novice",
                        "RoomName": "",
                        "CustomerName": "topaz",
                        "UserName": "XXXX@outlook.com"
                    }
                }
            ]
        }
    }
}

Contoh skema array dan struktur berlapis

Saat Anda mencetak skema bingkai data objek (disebut df) dengan perintah df.printschema, Anda akan melihat representasi berikut:

  • Kuning mewakili struktur berlapis.
  • Hijau mewakili array dengan dua elemen.

Kode dengan penyorotan kuning dan hijau, memperlihatkan asal skema

_rid, _ts, dan _etag, telah ditambahkan ke sistem karena dokumen itu dimasukkan ke dalam simpan transaksional Azure Cosmos DB.

Bingkai data sebelumnya hanya dihitung untuk 5 kolom dan 1 baris. Setelah transformasi, bingkai data yang dikuratori akan memiliki 13 kolom dan 2 baris, dalam format tabular.

Meratakan struktur berlapis dan meledakkan array

Dengan Spark di Azure Synapse Analytics, mudah untuk mengubah struktur berlapis menjadi kolom dan elemen array menjadi beberapa baris. Gunakan langkah-langkah berikut untuk implementasi.

Bagan alur memperlihatkan langkah-langkah untuk transformasi Spark

Tentukan fungsi untuk meratakan skema berlapis

Anda dapat menggunakan fungsi ini tanpa perubahan. Buat sel di buku catatan PySpark dengan fungsi berikut ini:

from pyspark.sql.functions import col

def flatten_df(nested_df):
    stack = [((), nested_df)]
    columns = []

    while len(stack) > 0:
        parents, df = stack.pop()

        flat_cols = [
            col(".".join(parents + (c[0],))).alias("_".join(parents + (c[0],)))
            for c in df.dtypes
            if c[1][:6] != "struct"
        ]

        nested_cols = [
            c[0]
            for c in df.dtypes
            if c[1][:6] == "struct"
        ]

        columns.extend(flat_cols)

        for nested_col in nested_cols:
            projected_df = df.select(nested_col + ".*")
            stack.append((parents + (nested_col,), projected_df))

    return nested_df.select(columns)

Mendefinisikan fungsi untuk meratakan skema berlapis

Dalam langkah ini, Anda meratakan skema berlapis bingkai data (df) ke dalam bingkai data baru ( df_flat ):

from pyspark.sql.types import StringType, StructField, StructType
df_flat = flatten_df(df)
display(df_flat.limit(10))

Fungsi tampilan harus mengembalikan 10 kolom dan 1 baris. Array dan elemen berlapisnya masih ada.

Transformasi data

Di sini, Anda mengubah array, context_custom_dimensions, dalam bingkai data df_flat, menjadi bingkai data baru df_flat_explode. Dalam kode berikut, Anda juga menentukan kolom mana yang akan dipilih:

from pyspark.sql.functions import explode
from pyspark.sql.functions import flatten
from pyspark.sql.functions import arrays_zip
df_flat_explode = df_flat.select("_rid","_ts","id","_etag",explode(df_flat.context_custom_dimensions),"context_session_isFirst","context_session_id","context_data_eventTime","context_data_samplingRate","context_data_isSynthetic")\
.select("_rid","_ts","id","_etag","col.*","context_session_isFirst","context_session_id","context_data_eventTime","context_data_samplingRate","context_data_isSynthetic")
display(df_flat_explode.limit(10))

Fungsi tampilan harus memberikan 10 kolom dan 2 baris. Langkah selanjutnya adalah meratakan skema berlapis dengan fungsi yang ditentukan pada langkah 1.

Gunakan fungsi untuk meratakan skema berlapis

Terakhir, Anda menggunakan fungsi untuk meratakan skema berlapis dari bingkai data df_flat_explode, ke dalam bingkai data baru, df_flat_explode_flat:

df_flat_explode_flat = flatten_df(df_flat_explode)
display(df_flat_explode_flat.limit(10))

Fungsi tampilan harus memberikan 13 kolom dan 2 baris.

Fungsi printSchema bingkai data mengembalikan df_flat_explode_flat hasil berikut:

Kode memperlihatkan skema akhir

Membaca array dan struktur berlapis secara langsung

Dengan model SQL tanpa server, Anda dapat membuat kueri dan membuat tampilan dan tabel atas objek tersebut.

Pertama, tergantung bagaimana data telah disimpan, pengguna harus menggunakan taksonomi berikut. Semua yang ditampilkan dalam huruf besar khusus untuk kasus penggunaan Anda:

/Bulk Format
'https://ACCOUNTNAME.dfs.core.windows.net/FILESYSTEM/PATH/FINENAME.parquet' 'Parquet' (ADLSg2)
N'endpoint= https://ACCOUNTNAME.documents-staging.windows-ppe.net:443/ ;account=ACCOUNTNAME;database=DATABASENAME;collection=COLLECTIONNAME;region=REGIONTOQUERY', SECRET='YOURSECRET' 'CosmosDB' (Azure Synapse Link)

Ganti setiap bidang sebagai berikut:

  • 'BULK ABOVE ANDA' adalah string koneksi dari sumber data yang Anda sambungkan.
  • 'TIPE ANDA DI ATAS' adalah format yang Anda gunakan untuk menyambungkan ke sumbernya.
select *
FROM
openrowset(
    BULK 'YOUR BULK ABOVE',
    FORMAT='YOUR TYPE ABOVE'
)
with (id varchar(50),
        contextdataeventTime varchar(50) '$.context.data.eventTime',
        contextdatasamplingRate varchar(50) '$.context.data.samplingRate',
        contextdataisSynthetic varchar(50) '$.context.data.isSynthetic',
        contextsessionisFirst varchar(50) '$.context.session.isFirst',
        contextsessionid varchar(50) '$.context.session.id',
        contextcustomdimensions varchar(max) '$.context.custom.dimensions'
) as q 
cross apply openjson (contextcustomdimensions) 
with ( ProfileType varchar(50) '$.customerInfo.ProfileType',
            RoomName varchar(50) '$.customerInfo.RoomName',
            CustomerName varchar(50) '$.customerInfo.CustomerName',
            UserName varchar(50) '$.customerInfo.UserName'
    )

Ada dua jenis operasi yang berbeda:

  • Tipe operasi pertama ditunjukkan dalam baris kode berikut, yang menentukan kolom yang disebut contextdataeventTime yang merujuk ke elemen berlapis, Context.Data.eventTime.

    contextdataeventTime varchar(50) '$.context.data.eventTime'
    

    Baris ini mendefinisikan kolom yang disebut contextdataeventTime yang merujuk ke elemen berlapis, Context>Data>eventTime.

  • Tipe operasi kedua digunakan untuk cross apply membuat baris baru untuk setiap elemen di bawah array. Kemudian mendefinisikan setiap objek yang ditumpuk.

    cross apply openjson (contextcustomdimensions) 
    with ( ProfileType varchar(50) '$.customerInfo.ProfileType', 
    

    Jika array memiliki 5 elemen dengan 4 struktur bererlapis, model SQL tanpa server mengembalikan 5 baris dan 4 kolom. Model SQL tanpa server dapat meminta di tempat, memetakan array dalam 2 baris, dan menampilkan semua struktur berlapis ke dalam kolom.

Langkah berikutnya