Share via


Azure Synapse Analytics'te karmaşık veri türlerini analiz etme

Bu makale, Azure Cosmos DB için Azure Synapse Link'teki Parquet dosyaları ve kapsayıcılarıyla ilgilidir. Diziler veya iç içe yapılar gibi karmaşık şemalarla verileri okumak veya dönüştürmek için Spark veya SQL kullanabilirsiniz. Aşağıdaki örnek tek bir belgeyle tamamlanmıştır, ancak Spark veya SQL ile milyarlarca belgeye kolayca ölçeklendirilebilir. Bu makalede yer alan kod PySpark (Python) kullanır.

Kullanım örneği

Karmaşık veri türleri giderek daha yaygın hale geldi ve veri mühendisleri için bir zorluğu temsil ediyor. İç içe şemayı ve dizileri çözümlemek zaman alan ve karmaşık SQL sorgularını içerebilir. Buna ek olarak, iç içe sütunların veri türünü yeniden adlandırmak veya değiştirmek zor olabilir. Ayrıca, iç içe nesnelerle çalışırken performans sorunlarıyla karşılaşabilirsiniz.

Veri mühendislerinin karmaşık veri türlerini verimli bir şekilde işlemeyi ve bunların herkes tarafından kolayca erişilebilir olmasını sağlamayı anlaması gerekir. Aşağıdaki örnekte, veri çerçeveleri aracılığıyla nesneleri okumak ve düz bir yapıya dönüştürmek için Azure Synapse Analytics'te Spark'ı kullanırsınız. bu tür nesneleri doğrudan sorgulamak ve bu sonuçları normal bir tablo olarak döndürmek için Azure Synapse Analytics'te SQL'in sunucusuz modelini kullanırsınız.

Diziler ve iç içe yapılar nedir?

Aşağıdaki nesne Application Insights'tan gelir. Bu nesnede, iç içe yerleştirilmiş yapılar ve iç içe yapıları içeren diziler vardır.

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

Dizilerin ve iç içe yapıların şema örneği

komutuyla df.printschemanesnenin veri çerçevesinin şemasını (df olarak adlandırılır) yazdırırken aşağıdaki gösterimi görürsünüz:

  • Sarı iç içe yapıları temsil eder.
  • Yeşil, iki öğe içeren bir diziyi temsil eder.

Şema kaynağını gösteren sarı ve yeşil vurgulamalı kod

_rid, _tsve _etag belge Azure Cosmos DB işlem deposuna alındığında sisteme eklendi.

Önceki veri çerçevesi yalnızca 5 sütun ve 1 satır için sayılır. Dönüştürmeden sonra, seçilen veri çerçevesinin tablo biçiminde 13 sütunu ve 2 satırı olur.

İç içe yapıları düzleştirme ve dizileri patlatma

Azure Synapse Analytics'teki Spark ile iç içe yapıları sütunlara ve dizi öğelerini birden çok satıra dönüştürmek kolaydır. Uygulama için aşağıdaki adımları kullanın.

Spark dönüştürme adımlarını gösteren akış çizelgesi

İç içe şemayı düzleştirmeye ilişkin bir işlev tanımlama

Bu işlevi değişiklik yapmadan kullanabilirsiniz. PySpark not defterinde aşağıdaki işlevi kullanarak bir hücre oluşturun:

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)

İç içe şemayı düzleştirmek için işlevini kullanma

Bu adımda, veri çerçevesinin iç içe şemasını (df) yeni bir veri çerçevesine (df_flat):

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

Görüntüleme işlevi 10 sütun ve 1 satır döndürmelidir. Dizi ve iç içe öğeleri hala oradadır.

Diziyi dönüştürme

Burada, veri çerçevesindeki df_flatdizisini context_custom_dimensionsyeni bir veri çerçevesine df_flat_explodedönüştürürsiniz. Aşağıdaki kodda, hangi sütunun seçılacağını da tanımlarsınız:

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))

Görüntüleme işlevi 10 sütun ve 2 satır döndürmelidir. Sonraki adım, 1. adımda tanımlanan işlevle iç içe şemaları düzleştirmedir.

İç içe şemayı düzleştirmek için işlevini kullanma

Son olarak, işlevini kullanarak veri çerçevesinin df_flat_explodeiç içe şemasını yeni bir veri çerçevesinde df_flat_explode_flatdüzleştirirsiniz:

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

Görüntüleme işlevi 13 sütun ve 2 satır göstermelidir.

Veri çerçevesinin df_flat_explode_flat işlevi printSchema aşağıdaki sonucu döndürür:

Son şemayı gösteren kod

Dizileri ve iç içe yapıları doğrudan okuma

SQL'in sunucusuz modeliyle, bu tür nesneler üzerinde görünümler ve tablolar sorgulayabilir ve oluşturabilirsiniz.

İlk olarak, verilerin nasıl depolandığına bağlı olarak, kullanıcıların aşağıdaki taksonomiyi kullanması gerekir. Büyük harfle gösterilen her şey kullanım örneğine özeldir:

Toplu Biçimlendir
'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 Bağlantısı)

Her alanı aşağıdaki gibi değiştirin:

  • 'ÜST ÜSTE TOPLU İŞİ' bağlandığınız veri kaynağının bağlantı dizesidir.
  • 'YUKARıDAKİ TÜRÜNÜZÜN' biçimi, kaynağa bağlanmak için kullandığınız biçimdir.
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'
    )

İki farklı işlem türü vardır:

  • İlk işlem türü, iç içe öğeye Context.Data.eventTimebaşvuran adlı contextdataeventTime sütunu tanımlayan aşağıdaki kod satırında gösterilir.

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

    Bu satır, iç içe öğeye Context>Data>eventTimebaşvuran adlı contextdataeventTime sütunu tanımlar.

  • İkinci işlem türü, dizinin altındaki her öğe için yeni satırlar oluşturmak için kullanır cross apply . Ardından her iç içe nesneyi tanımlar.

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

    Dizide 4 iç içe yapıya sahip 5 öğe varsa, SQL'in sunucusuz modeli 5 satır ve 4 sütun döndürür. SQL'in sunucusuz modeli yerinde sorgu yapabilir, diziyi 2 satır halinde eşleyebilir ve tüm iç içe yapıları sütunlar halinde görüntüleyebilir.

Sonraki adımlar